CS 112 Fall 2016 -- Homework Two

Due Monday, July 10th at Midnight.

No late assignments will be accepted! Honestly, I will not be downloading the submissions until the next morning, but when I do so, no other submissions will be accepted!

Introduction

This homework has two parts: in Part A you will write up answers to analytical problems related to the lectures in the past week, both to confirm and extend your understanding of the abstract principles discussed; in Part B you will write code to implement this understanding, and to practice your Java coding skills. I suggest you read this whole assignment carefully and for Part B, it is definitely worth thinking about your solution for a bit before launching Eclipse and beginning to type.

Consult the textbook and the Java online documentation as needed.

Part A: Analytical Problems (10 points)

The questions below are designed to reinforce the material exposed to you at lecture and from assigned readings. You MUST do these by hand (without typing them into Eclipse) to verify understanding; you may of course check your answers, but if you do not do these by hand first, you will be unable to answer such questions on a test!

NOTE: From now on, please submit your answers to the Part A problems as text files (.txt) and do NOT submit .pdf, .jpg, or any other kind of file.

  1. What's wrong with the following program? State as many errors as possible that (individually) would prevent the program from compiling without error:
  2. Public class test1 {
      public static integer f( x ) {
        if(x = 5)
           x = 1;
      }
      public static void main [String[] argv] {
      {
        System.println('Hello World!')   
      }
    )
    
  3. What would the following program print out? You MUST be able to do this kind of problem WITHOUT simply running the code and pasting the result into your answer.
  4. public class test2 {
    public static void main (String[] argv)
    { System.out.println( (double) (int) 3.1415 );
    int i = 10;
    while (i >= 1)
    System.out.println(i);
    --i;
    }
    }
  5. What would the following program print out? You MUST be able to do this kind of problem WITHOUT simply running the code and pasting the result into your answer.
  6. public class test3 {
      
      public static void main (String[] argv) 
      {
        int[] A = { 1, 1, 1, 1 };    // this initializes an array of length 4 with all values being 1
        for(int i = 0; i < 4; ++i) {
          for(int j = i-1; j >=0; --j) {
             A[i] +=  A[j];
          }
        }
        for(int i = 0; i < 4; ++i)
          System.out.println(A[i]); 
      }
    
    }
  7. What would the following program print out? You MUST be able to do this kind of problem WITHOUT simply running the code and pasting the result into your answer.
  8. public class test4 {
      
        public static void main (String[] argv) 
        {
            int[] A = { 1, 2, 3, 4, 5, 6 };    
            for(int i = 0; i < A.length; ++i) {
                if( A[i] % 2 == 0 )
                    continue;
                else if( A[i] > 4 )
                    break;
                else
                    A[i] *= 2;
            }
            for(int i = 0; i < A.length; ++i)
                System.out.println(A[i]); 
        }
    
    }
    
  9. In the following program, for each name A, B, C, D, E, F, G of a variable or method, state the locations (1 to 9) which are in the scope of the variable. For example, for location A you would write "1 - 9" or "all".
  10. public class ScopeTest {
    
        public static int A = 2;
    
        // location 1
    
        public static void B( int C ) {
             // location 2
        }
    
        public static void main (String[] argv) 
        {
            // location 3
            int D = 2;    
            // location 4 
            for( int E = 0; E < 10; ++E ) {
                // location 5
                if( D < A ) {
                    int F = 1;
                    // location 6
                }
                // location 7
           }
           // location 8
        }
    
    // location 9
    
      public static int G = 2;
    
    }
    

I REPEAT: I strongly recommend you work out the problems WITHOUT trying them in Eclipse, and only after thinking them through and coming up with an answer then try them out in Eclipse. If you simply type them in to get the answer without much thinking, then you will be unable to solve such problems on a test, and MOST IMPORTANTLY, you won't learn the principles being taught!

Write your answers to these questions as a file hw02.txt, and hand in as part of your homework submission into the hw02 folder in Websubmit.

Part B: Programming Problems (90 pts)

Useful String Methods (Please read this through before starting the problems)

In this homework, we will continue to explore using Java to do input and output, and in particular focus on using Strings; you should read through the follow material before starting the problems. In addition, here is a simple reference on Strings. Googling "Java String library" or "Java Character library" will produce many references with explanations about these libraries For full details, he canonical reference on these libraries is the Oracle online Java page, which contains every detail you need to know: String, Character. For this assignment, these are a bit of overkill, but you should know about them.

Finally, if you don't mind the fact that he uses Dr. Java instead of Eclipse, it is worth looking at Aaron Steven's Java videos 14 and 14b (Aaron is one of our BU instructors).

Note: Each method is followed by examples, assuming the initial declaration String str = "Hi There" and where "=>" means "returns the value"; these are methods that are called in conjunction with the String variable, using the "dot notation" as shown in the examples.

String str = "Hi There";

charAt( n ) -- returns the character at the given index n in the string (starts at 0):

str.charAt(1) =>'i'

NOTE: You CAN NOT change a String by doing for example:

str.charAt(1) = 'h'

Strings are immutable, and to change a String you have to create a new one!

toLowerCase() -- converts all letters to lower case;

str.toLowerCase() => "hi there"

str = str.toLowerCase(); // this is how you convert the string str to lower case

equals( str2 ) -- Returns true or false depending on whether the string is equal to the parameter

str.equals("hi There") => false

str.equals("Hi There") => true

Note: DO NOT use == to compare Strings, this is almost always the wrong thing to do!

replace(...) -- Create a new String where all occurrences of one substring are replaced by another -- the original String is unchanged.

str.replace("Hi", "Hello") => "Hello There"

str.replace("e", "") => "Hi Thr"

str = str.replace("e", ""); // remove all occurrences of the character 'e' from str

 

replaceFirst(...) -- Create a new String where the first occurrence one substring is replaced by another -- the original String is unchanged.

str.replaceFirst("Hi", "Hello") => "Hello There"

str.replaceFirst("e", "") => "Hi Thre"

str = str.replaceFirst("e", ""); // remove the first occurrence of the character 'e' from str

length() -- Return the length (number of chars in) the String. NOTE that this is different from the way you find the length of an array: A.length

str.length() => 8

split("\\s+") -- Separate each String into separate strings using the white space between them as a separator and put them in an array (here we are giving you the parameter which does this, others can be used as well).

String[] words = str.split("\\s+");

// words is now the array ["Hi", "There"]

 

Useful Character library methods (the first three of these return boolean values; read about here)

Note: these methods are called using the "dot notation" but with the name of the library, NOT the name of a variable. The first two will not be used in this lab, but you should learn about them, since we will surely use them soon!

Character.isLetter( c )           // returns true or false depending on whether the character c is a letter

      Character.isLetter( 'A' ) => true
      Character.isLetter( '9' ) => false

Character.isDigit( c )

Character.isWhitespace( c )       // returns true if character is defined as whitespace on your computer   

Character.toString( c )            // converts a character to a String
   
       String s = Character.toString( 'A' );     // s will have the value "A"
                                                 // Think of this as typecasting a char to a String

Note: You can also just use the Character in a String context, e.g., System.out.println("Hi" + ' ' + "There!)

Problem B.1 (30 points)

Now download StringTest.java and run it; you will see that it inputs a sequence of strings and simply prints them out between double quotes. It will continue to do this until you type Control-d (hold down the Control key and hit the letter "d").

For this problem, you must rewrite StringTest.java into a program PalindromeTest.java, which will read in a string, which is assumed to be an English sentence, and check whether it is a palindrome (reads the same backwards as forwards). Here are the steps you should follow:

1. Read in the string and convert it to all lower case using toLowerCase();

2. Remove any character which is neither a letter nor a digit; you can use Character.isDigit(...) and Character.isLetter(...) to test for this. All punctuation and white space will be remove. (Hint: use replace(....) to replace any non-letter non-digit by the empty String "").

3. Using charAt(...) check if the word is a palindrome by checking if each letter is the same as the letter in its "mirror image" position; for example "Taco Cat" and "Toot!" are palindromes:

but "honor" is not.

NOTE: You may NOT do the problem by converting the String to a char array first; I want you to use the String methods! Another possible way to do this problem is to reverse the String and then compare if they are equal; again, you may NOT do the problem this way, but must follow my requirements above.

Test your code on the following palindromes:

A man, a plan, a canal, Panama!

Go hang a salami, I'm a lasagna hog!

Campus Motto: Bottoms up, Mac!  
7/1/17                                    // A recent palindrome date!

Are we not pure "No sir!" Panama's moody Noriega brags. It is garbage! Irony dooms a man; a prisoner up to new era.    

(Other examples are given at the bottom of this lab!)  
(Warning: This last one might cause a problem because there are various kinds of "smart quotes" which are different from the simple ASCII double quotes; if all the others work and this one doesn't, don't worry about it!)

Also test your code on a non-palindrome example -- such as the word "palindrome" itself, or this sentence!

Just print out "Palindrome!" or "Not a palindrome!" depending on your answer. Here is an example of what your program should do:

Other Palindromes:

 

Problem B.2 (30 points)

Now you will rewrite your problem to test for a different kind of palindrome -- instead of having mirror images of characters, a Word Palindrome has mirror images of words; often these are given as Palindrome Poems or Mirror Poems:

Spoken Breath
Creating flesh and spirit
Spirit and flesh creating
Breath spoken.

// You would have to type this in on a single line in Eclipse to avoid the newlines (the backslashes
// are a typical way of indicating line breaks in a poem when putting it all in one line)

Spoken Breath /  Creating flesh and spirit / Spirit and flesh creating / Breath spoken.         

Write a program WordPalindromeTest.java which tests whether your input String is a word palindrome. Here is what you must do:

  1. Read a line from the console and convert it to lower-case and then remove any character which not a digit, not a letter, and not white space (i.e., we need to keep the white space to do the split in the next step);
  2. Convert the String into an array of Strings, using split("\\s+") as shown above;
  3. Adapt your algorithm from the first problem to test for equality of arrays of Strings instead of individual Strings, using equals(...) as shown above;
  4. Print out the array of words (this will help with debugging), and then your answer;
  5. Demonstrate your code on the poem shown above and also on the sentence "This is not a word palindrome!" Remember that you have to type it all in one line without carriage returns; you may use the slash or not to indicate end of lines.

This problem is a good example of a typical programming paradigm: you have an existing program, and you need to modify it to accomplish some related purpose. When I created my solution to this second problem, I copied the solution to the first problem to a new file, and modified it -- it took me less than a minute to have a working solution for the second problem (you may take a bit longer, of course!). We will be talking about this paradigm much more next week!

Here is an example of how your program should behave:

 

Another Word Palindrome:

Life-
imitates nature,
always moving, traveling continuously.
Continuously traveling, moving always,
nature imitates
life.

Copyright © 2002 Lynne C. Fadden // this line is not part of the poem!

Problem B.3 (30 points)

Write a program Histogram.java which accepts up to 20 doubles from the user, and prints out a histogram of the values, i.e., it counts the number of numbers which are in the ranges [0..10], (10..20], (20..30], ...., (90..100], where [a..b] denotes the set of numbers x such that a <= x <= b and (a..b] denotes the set of numbers x such that a < x <= b. Any input number outside the range [0..100] is an error, and the program should report the error and ask for a correct input. The program should output the number of input values, list them, and then display the histogram, as shown in the screenshots near the bottom of this document. You should recreate these as closely as possible, and in addition observe the following requirements:

(i) You must store the numbers input in an array, e.g., double[] number = new double[ ... ]; to read in the doubles, use hasNextDouble() and nextDouble() from the Scanner class, instead of hasNextLine() and nextLine(); you will need to figure out how to keep track of how many numbers you have read in.

(ii) You must store the counts for the various ranges in an array, e.g., int[] histogram = new int[ ... ];

(iii) The user may input at most 20 numbers, all between 0 and 100 inclusive, and you should do error checking and reporting as shown in the screen-shots below.

(iv) You must calculate which range an input falls in by using a loop, i.e., you may NOT simply write out all possibilities, e.g.,

if(number <= 10.0) {           // VERY BAD SOLUTION
  ++histogram[0];
}
else if(number <= 20.0) {
  ++histogram[1]; 
}
etc.

(v) Similarly, you must print out each row of the histogram using a loop, and may NOT simply write out all possibilities, e.g.,

    System.out.println("[0..10]" + ....etc.     // VERY BAD SOLUTION 
    System.out.println("(10..20]" + ....etc.  
In order to do this, you will need to use a tab character to line up the beginnings of the rows of asterisks. (The point of these last two requirements is that you should begin to think about how to make your programs general enough that if you want to change them later, it will not be so much trouble.)

(vi) You must print out the introductory Welcome message using a method (which needs no parameters)

public static void printHeading() { 
    ....                                  // I will write "...." when you need to fill in code!
}  

(vii) You must print out the histogram at the end using a method

public static void printHistogram( ... ) { 
    ....
}  

(viii) You must write a method as follows to figure out if the inputs are in the legal range [0.0 .. 100.0]:

public static boolean validInput( ... ) {
    ....
}  

(ix) You must store the maximum number of inputs (20) and the number of bins in the histogram (10) in final instance variables (also called field or class variables); you should NOT have the numbers 20 or 10 occur anywhere in your program except in the declarations of these variables. You MUST do this so that if you decide to change one of these, you don't have the "multiple update" problem. Here is an example of what you should use:

import java.util.Scanner;

public class Histogram { 
    
    public static final int MAX_NUMBERS = 20;             // maximum number of numbers to input
    public static final int NUM_BINS    = 10;              // number of bins in range [0..100]
    
    public static void main(....) etc. 

Note that there are two places where the number 10 might be used, first with the number of bins, and second the size of each bin. It is a coincidence that these are the same, but in general they might not be; that is, you have numbers in the range [0..100] and so here is the relationship:

          number of bins        size of bins
               10                   10                       i.e.,  [0..10], (10..20], ...., (90..100]
                5                   20                       i.e.,  [0..20], (20..40]  ...., (80...100]
                2                   50                       i.e.,  [0..50], (50..100]

Clearly the size = 100 / number of bins.   When number of bins is 10, then so is the size, but this is a coincidence. 

Here is what I did, and I recommend you do the same: First, don't worry about the possible error when the number of bins does not divide evenly into 100 (we'll run your program as is, and won't change the number of bins from 10 to something else). Second, declare ANOTHER final variable say BIN_SIZE and calculate it from the number of bins

public static final BIN_SIZE  =  100 / NUM_BINS;                     Note: put this after the declaration of NUM_BINS!

Then use NUM_BINS where 10 means the number of bins and BIN_SIZE where 10 means the increment from one bin range to the other. Alternately, you could use ( 100 / NUM_BINS )  when you need the increment. 

You can leave 100 as a number, because this is an essential quantity that doesn't change. 

The idea is that any time you might possibly want to change some number, you should make it final. Numbers like 1, 3.1415, etc. don't have to be treated so generally, and in this case, 100 is a number that won't ever change.

Examples Sessions of Histogram.java:

 

Submission

Submit all files into the Websubmit program by the due date and time; the time of submission will be when the LAST file is uploaded. Instructions for using Websubmit are on the class web site.

Here is a check list to follow in order to make sure you have completed this homework correctly:

Submit files (submit all into hw02 folder in websubmit and do NOT put anything into the lab folders):

Check: