CSCI 151 - Lab 1 Just Java-ing around

Due 10:00pm, Sunday, 17 Sep 2017

Assignment Description

In this lab you will be writing a number of short programs to get some practice working with Java. The goals of this lab are to

If you've not done so, I strongly suggest you do Lab 0 first.

Part 1 - Getting Started

Let's get this programming party started!

Getting organized

First, you should create a separate folder for your solutions.

% cd
% mkdir cs151 # skip if you already did lab0
% cd cs151
% mkdir lab1
% cd lab1

Create the Java project in Eclipse

If you are writing your programs in Eclipse, you can now create the project.

  1. Start up Eclipse by typing eclipse & on the command line
  2. Select "File" > "New" > "Java Project"
  3. Call it "Lab 1" (or whatever you want)
  4. For the location use the "Browse" button to select the lab1 folder you created earlier
  5. Now select "Finish"

Unlike most of the other labs, this one will consist of a number of small programming assignments to give you a chance to become familiar with programming in Java.

Part 2 - Pyramids revisited

For your first program I want you to create a class called Pyramid that draws a simple pyramid out of * characters. Your program should

  1. Using the String array parameter to main called args, check that args.length is equal to 1. If it isn't, you should print a message to the user and then quit by calling System.exit(1);

    For reference, here is a program that will print out all of the arguments to the main method:

        public static void main(String[] args) {
            for ( int i = 0; i < args.length ; i++) {
                System.out.println( "Argument " + i + " is " + args[i] );
            }
        }
            

  2. Integer.parseInt is a static method in the Integer class that allows you to convert a String that represents a number and turn it into an int. Use Integer.parseInt to convert the first argument args[0] into an int for the height of your pyramid
    int height = Integer.parseInt(args[0]);
  3. Print out the pyramid

Here are some examples of it running:

% java Pyramid 5
    *
   ***
  *****
 *******
*********

% java Pyramid 1
*

% java Pyramid
Usage: java Pyramid <height>

Part 3 - What number am I thinking of?

For this part, I want you to create a class called HiLo that plays a simple numeric guessing game. The computer will pick a number between 1 and 1000 and then the user will try to guess what it is.

To create a random number, you will need to create a Random object that will let you generate random numbers.

You then can use rnd.nextInt(1000) to get you a number between 0 and 999. Just add 1 to get it into the right range.

    Random rnd = new Random();
    int target = rnd.nextInt(1000) + 1;

Now you'll want to loop until the user guesses your number. Keep in mind that you can use break and continue to exit or go to the next iteration of a loop.

Use a Scanner object to read from System.in which will capture keyboard input. I recommend using 2 Scanners. The first you can use hasNextLine() and nextLine() to get an entire line of input from the user. Create a second Scanner using this String and then use hasNextInt() and nextInt() to see if the user actually typed a number and then retrieve it. If the line doesn't start with a number (i.e., hasNextInt returns false) you should print a message out to the user and loop back to where you read an entire line.

    int userGuess = -1;

    Scanner input = new Scanner(System.in);     // I'm reading what the user typed

    while ( input.hasNextLine() ) {         // keep looping for each guess, use 'break' to exit

        String line = input.nextLine();     // Read the next line of input from the user

        Scanner s2 = new Scanner(line);     // s2 will let me break 'line' apart

        if  ( s2.hasNextInt() ) {           // check to see if s2 would next see an integer number
            // Yay! do something with this
            userGuess = s2.nextInt();       // read in that number
        } else {
            // So sad, print a message and then...
            continue;                       // jump back to the top of the while loop
        }

        /* probably more here! This is just an example, you know? */

    }

Keep track of the number of valid guesses the user makes and let them know how they did at the end.

Let's play a game!
I'm thinking of a number between 1 and 1000
Try to guess what it is!

Enter a guess: 500
Too low!

Enter a guess: 750
Too high!

Enter a guess: 625
Too low!

Enter a guess: -72
Too low!

Enter a guess: kittens
That's not a number, try again.

Enter a guess: 630
Too high!

Enter a guess: 629
You guessed my number!  It took you 6 tries.

Part 4 - Redaction

One of the meanings of the word "redaction" is to censor, or to delete specific words or phrases from a document. The subject of redacted documents has been in the news recently. Let's try our hand at automatically redacting some documents.

Create a java program called Redactor that takes a list of files on the command line. The first file contains a list of words to be redacted, the remaining files are the ones to be processed.

Go through the first file and read in the list of words to be redacted. Store them in an array of Strings.

    String[] wordlist;
You will need to create the array to be large enough to hold all of the words in the file. HINT: If you make a new Scanner from the same file name, you will start reading from the beginning once again. You will probably need to read the file once to count the words, and then once more to actually store them in an array.

Now go through the remaining list of filenames specified on the command line and redact them. For each I want you to try and open them up using a Scanner. Then you should read them line by line. For each line, take each word and see if matches one on your wordlist. If it does, then you should print XXXXXX instead of the word. If it doesn't, just print the word as is. You should have spaces between the words you print, and the words should be on the same line as they were in the input file, but you can otherwise ignore whitespace.

For this program, you only need to handle exact matches. You might note in the example below that words ending with a ',' don't count as matches in this case.

Handling missing files

We should have talked about using a try/catch block to handle the case where a Scanner cannot open a File. Print out the exceptions message when this occurs. If the file that can't be opened is the list of words to be redacted then you should exit using System.exit(1); otherwise you should print out the message and try the next file in the list.

Recall that you will need something like the following (NOTE: you can't just use this as-is in your program):

    Scanner input = null;   // we will have to do this to appease the compiler
    try {
        input = new Scanner(new File("input.txt"));     // you'll probably want args[0] 
                                                        // or similar here at some point
    } catch (FileNotFoundException e) {
        System.out.println("Problem opening file: " + e.getMessage());
        System.exit(1);
    }

We have pulled a couple of articles from the Oberlin Review for you to try your redactor on: lab1-news.zip

You can either save this file to your machine and then move it into the lab1 directory, or you can (more easily) just copy the URL and then download the files from the command line using wget.

% wget http://www.cs.oberlin.edu/~rhoyle/16s-cs151/lab01/lab1-news.zip

Here are the first 30 lines of one of the news files being redacted:

% java Redactor wordlist.txt news-big-win.txt

Processing news-big-win.txt
The XXXXXX Review 

Sunday, September 8th, 2013 
Established 1874 
____________________ 

XXXXXX XXXXXX Win Big Over Denison 

by Rose Stoloff 

April 11, 2013 

After a long winter hiatus, the XXXXXX Squirrels, XXXXXX co-ed club 
soccer team, had their first victory of the year on Saturday, defeating 
Denison University 3-1. This was the team's fourth game of the year and 
its first game of the spring season. 

The XXXXXX came out strong and defended their home turf, finding the 
back of the net early on. Senior Evan Baker scored his first goal ever, 
according to his teammates, after finishing a cross by first-year 
standout Sarah Mills. 

"Evan just jumped higher than everyone else. It was a really nice 
header," said senior captain Edward Russell. Mills added that Evan was 
the "MVP of the game." 

The XXXXXX XXXXXX lost some of their strength in the latter portion 
of the half. "We sort of fell apart and we were defending for the rest 

Part 5 - Benford Analysis

Benford's Law also known as the "first-digit law" is an observation about the distribution of digits in numbers in data sources. In brief, in many natural datasets the first digit will be a '1' about 30% of the time with each higher digit occurring less frequently than the previous ending with a '9' occurring less than 5% of the time.

There is a nice graph of this distribution on the Wikipedia page: http://en.wikipedia.org/wiki/Benford's_law#Mathematical_statement

Counting first digits

For this program, you are only concerned about words that start with a numerical digit, and then you need to get the value of that digit. You'll need to maintain a count of the number of words you encounter that start with the digits 0 through 9. You should do this in an array and use the digit as the index into the array.

There are a number of ways you could get at the first character, determine if it is a digit, and get the value. One way might be to:

  1. Get a word from your input (probably using Scanner and hasNext() / next()
  2. Use the word's charAt() method to get the first character and pass it into Character.isDigit() to determine if it is a digit.
  3. If it is, then you can use the word's substring method to extract that first digit as a String
  4. And that new String can be passed into Integer.parseInt to determine the integer value.

Processing files

This program will be very similar to some of the ones you have already worked on. You will give a list of files on the command line and then your program will work through all of them. If a file cannot be opened, just print a message to the user and continue on.

Printing out the frequency chart

Once you have gone through and made a count of all your leading digits, you should print out a histogram of the various frequencies that you encountered. You should should print out the following information for each row:

  1. The leading digit 0-9
  2. The total count of words beginning with that digit
  3. The frequency of that digit being at the start of words beginning with digit
  4. A bar of * characters representing the frequency graphically

The most frequently occurring digit should have a bar of length MAXWIDTH where that is defined by a constant in your class.

    public static final int MAXWIDTH = 50;

All other bar's lengths should be scaled proportionally to this. So take the digit's count, divide by the max count, and multiple by MAXWIDTH. You should round this number using Math.round() to get it to the nearest integer.

So if all the frequencies are about even, you'd expect all the bars to be about 50 units wide. If they are more varied, then the longest will be 50 and the others will be of various shorter widths. Note that if the frequency is 0, the bar should have 0 '*' characters.

To print out the table in a formatted fashion, you might want to use System.out.printf to do things. You can pass it a format string that uses %d for decimal numbers and %f for floating point numbers. You can also specify a width for each field by including a number between the % and the letter. Here is what I used in the example shown below:

    System.out.printf("%d %8d %4.1f%% : ", digit, count[digit], freq );

Sample data

I collected a number of pieces of sample data for you to try out your Benford analysis tool on: lab1-numbers.zip

Because these are large files, and I don't want you to turn them in, they are all in a subfolder called "numbers".

This data comes from the US Census Bureau, CIA World Factbook, and a variety of other sources around the web. Try running your tool on the various files. Note in your comments for your program which ones seem to follow Benford's law and which ones don't. Feel free to speculate why the ones that don't are that way.

% java Benford numbers/census-pop-est.txt
Welcome to the Benford analysis program

0     1116  0.9% : **
1    35294 29.8% : **************************************************
2    20825 17.6% : ******************************
3    14070 11.9% : ********************
4    11405  9.6% : ****************
5     9210  7.8% : *************
6     8019  6.8% : ***********
7     6809  5.7% : **********
8     6472  5.5% : *********
9     5259  4.4% : *******

% java Benford numbers/census-pop-est.txt kittens numbers/primes-10000.txt
Welcome to the Benford analysis program
Could not open kittens (No such file or directory)

0     1116  0.9% : **
1    36898 28.7% : **************************************************
2    21954 17.1% : ******************************
3    15167 11.8% : *********************
4    12474  9.7% : *****************
5    10265  8.0% : **************
6     9032  7.0% : ************
7     7836  6.1% : ***********
8     7475  5.8% : **********
9     6265  4.9% : ********

handin

Look through your programs and make sure you've included your name at the top of all of them. Be sure to include your analysis of the Benford's law distributions in that file. If you adhered to the honor code in this assignment, add the following statement at the top of your Benford.java file:

I have adhered to the Honor Code in this assignment.

If there are portions of these programs that you know are not working correctly, you should include that in a comment section near the top of the buggy file.

handin

You now just need to electronically handin all your files.

Please delete the numbers folder before handing things in. It is about 20MB in size and we have our own copy. Thanks!

    % cd          # changes to your home directory
    % cd cs151    # goes to your cs151 folder
    % handin      # starts the handin program
                            # class is 151
                            # assignment is 1
                            # file/directory is lab1

    % lshand      # should show that you've handed in something

You can also specify the options to handin from the command line

    % cd ~/cs151                 # goes to your cs151 folder
    % handin -c 151 -a 1 lab1

Last Modified: August 22, 2016 - Roberto Hoyle, based on material from Benjamin Kuperman