Second Summer 2002


Lab Notes Three: Basic programs. Simulating decisions. Working with objects.

1. First a review. Of the problems presented for your practice last week, on Thursday, I want to highlight a few, wherein a few stunts (which most clearly justify the problems' difficulty) are worth pointing out. Here, first, is Two.java with formulas for max and min:

class Two {
    public static void main(String[] args) { 
        ConsoleReader console = new ConsoleReader(System.in); 
        System.out.print("Please enter your first integer number, ");  
        System.out.println("then press Enter.");
        int n1 = console.readInt(); 
        System.out.print("Please enter your second integer number, ");  
        System.out.println("then press Enter.");
        int n2 = console.readInt(); 
        int sum = n1 + n2; 
        System.out.println(n1 + " + " + n2 + " = " + sum); 
        int diff = n1 - n2; 
        System.out.println(n1 + " - " + n2 + " = " + diff); 
        int prod = n1 * n2; 
        System.out.println(n1 + " * " + n2 + " = " + prod); 
        double avg = sum / 2.0; 
        System.out.println("avg(" + n1 + ", " + n2 + ") = " + avg);
        int dist = Math.abs(n1 - n2); 
        System.out.println("dist(" + n1 + ", " + n2 + ") = " + dist); 
        long max = Math.round(avg + dist / 2.0); 
        // neat trick; can you explain it? 
        System.out.println("max(" + n1 + ", " + n2 + ") = " + max); 
        long min = Math.round(avg - dist / 2.0); 
        // neat trick; can you explain it? 
        System.out.println("min(" + n1 + ", " + n2 + ") = " + min); 
    } 
}
Regarding this problem I have three questions:
  1. Why are max and min declared as long?
  2. Would an if statement simplify this program?
  3. Can you compute Math.abs(...) without an if?

2. Three, Four, and Five are easy, mostly involving the application of a set of formulas, most of them well-known (and if you look closely I got two of them wrong, and marked them clearly as such). But have you managed to take a look at Six?

class Six {
    public static void main(String[] args) {
        // get a connection to the keyboard 
        ConsoleReader console = new ConsoleReader(System.in); 
        // ask the user for the amount due 
        System.out.println("Type the amount due then press enter."); 
        // read it 
        double due = console.readDouble(); 
        // ask the user for the amount received 
        System.out.println("Type the amount received then press enter."); 
        // read it 
        double received = console.readDouble(); 
        // assume received is bigger than due and compute difference 
        double difference = (received - due); 
        // you need to return this as change so make it a whole number
        // of cents regardless of how many decimals the user has entered  
        int diff = (int)(Math.round(difference * 100)); 
        // tell the user what change you are processing 
        System.out.println("Give " + diff / 100.00 + " in change as follows: "); 
        // number of quarters; integer division 
        int quarters = diff / 25; 
        // report it 
        System.out.println("   " + quarters + " quarters"); 
        // adjust the remaining change (modulo) 
        diff = diff % 25;
        // compute the number of dimes
        int dimes = diff / 10; 
        // report it 
        System.out.println("   " + dimes + " dimes"); 
        // adjust remaining cents (notice shortcut operator) 
        diff %= 10; // notice anything compared to the previous assignment? 
        // these are the cents 
        int cents = diff; 
        // report them too 
        System.out.println("   " + cents + " cents"); 
    } 
}
This problem uses integer arithmetic to transform a sum of money into a minimum number of coins (quarters, dimes, nickels, and cents) through a very interesting process. I have three questions with respect to this problem:
  1. Do you understand how the transformation process goes?
  2. Why do we use Math.round inside the program?
  3. Is there anything in the text on page 62 of relevance to this problem?

3. Seven is at the level of your homework assignment and a good exam problem. Eight simply places a comma in a String (and in only one place,) while Nine does the opposite. Based on Nine and Eight, how would you write a program that reads a String of at least two characters and then swaps the first and the last characters in the String as the following examples try to illustrate:

frilled.cs.indiana.edu%java Swap
Please type: pooh
After swapping pooh becomes: hoop
frilled.cs.indiana.edu%java Swap
Please type: twelve
After swapping twelve becomes: ewelvt
frilled.cs.indiana.edu%java Swap
Please type: donald
After swapping donald becomes: donald
frilled.cs.indiana.edu%
Remember that Strings are immutable objects!


4. Ten is easy, although it aims at a certain kind of optimization. But Eleven is tricky:

class Eleven {
    public static void main(String[] args) {
        // open a connection with the keyboard 
        ConsoleReader console = new ConsoleReader(System.in); 
        // tell the user to enter a number
        System.out.print("Please enter a number between 0 and 99999: "); 
        // read the number the user types 
        String number = console.readLine(); 
        // pad the number with five spaces 
        number = "     " + number; // thus string has at least 5 characters
        int i = number.length() - 1; // index of last char in string 
        // print the last five digits of the number 
        // note the order in which we print the chars and their indices 
        System.out.print(number.substring(i-4, i-3) + " "); 
        System.out.print(number.substring(i-3, i-2) + " "); 
        System.out.print(number.substring(i-2, i-1) + " "); 
        System.out.print(number.substring(i-1, i)   + " "); 
        System.out.print(number.substring(i)        + " \n"); 
    } 
}
Knowing how Eleven operates how would you write Reverse that reverses words of up to 6 characters in length, in a manner similar to the one illustrated below:
frilled.cs.indiana.edu%java Reverse
Please enter a word of up to 6 characters.
Type your word here: potato
potato reversed is: otatop
frilled.cs.indiana.edu%java Reverse
Please enter a word of up to 6 characters.
Type your word here: apple
apple reversed is: elppa
frilled.cs.indiana.edu%java Reverse
Please enter a word of up to 6 characters.
Type your word here: kiwi
kiwi reversed is: iwik
frilled.cs.indiana.edu%java Reverse
Please enter a word of up to 6 characters.
Type your word here: one
one reversed is: eno
frilled.cs.indiana.edu%java Reverse
Please enter a word of up to 6 characters.
Type your word here: um
um reversed is: mu
frilled.cs.indiana.edu%java Reverse
Please enter a word of up to 6 characters.
Type your word here: u
u reversed is: u   
frilled.cs.indiana.edu%java Reverse
Please enter a word of up to 6 characters.
Type your word here: 
 reversed is:       
frilled.cs.indiana.edu%

5. Twelve and Thirteen are different but routine. Fourteen however is downright mischievous. My only question is: why do I need the epsilon variable, at all, in Fourteen?


6. Fifteen is not only tricky, but also hides a subtle mistake. Here's where it fails:

frilled.cs.indiana.edu%java Fifteen
Please enter the first time: 1000
Please enter the second time: 0959
23 hours 59 minutes
frilled.cs.indiana.edu%java Fifteen
Please enter the first time: 1001
Please enter the second time: 1000
0 hours -1 minutes
frilled.cs.indiana.edu%java Fifteen
Please enter the first time: 1101
Please enter the second time: 1059
23 hours 58 minutes
frilled.cs.indiana.edu%java Fifteen
Please enter the first time: 0445
Please enter the second time: 0440
0 hours -5 minutes
frilled.cs.indiana.edu%
Can you see where the mistake is in the code?

To treat all cases correctly here's how we should solve Fifteen:

  1. Read String time1, and time2.
  2. For time1 split it into
    String hour1 = time.substring(0, 2),
           mins1 = time.substring(2); 
  3. Calculate time1 in minutes:
    int val1 = hour1 * 60 + mins1;
  4. Similarly calculate val2
  5. Then calculate the difference in minutes between the two:
    int diff = (val2 + 24 * 60 - val1) % (24 * 60); 
  6. Transform diff in hours and minutes:
    int resH = diff / 60, 
        resM = diff % 60; 
Write this program (call it MilitaryTime.java) and verify that it works correctly.

This just shows how important it is to prove the correctness of any program.


7. Problems Sixteen, Seventeen, and Nineteen are again routine, while Eighteen is featured in Lecture Notes Six. However, Nineteen produces random numbers, and I'd like to use this opportunity to point out a somewhat easier way of producing random numbers than the one suggested in the book.

Here's a way of producing random integers in the interval [a, b):

(int)(Math.random() * (b - a) + a)
If Math.random() returns a random number in [0, 1), can you see how this works?

I trust that you agree this batch of problems was not easy, and quite instructive!


And now the actual new part of the lab!

Goals for this lab:

Examples below are from the book, lecture notes, some (simple ones) are made up.


8. Lecture notes 3 contain an example like this:

public class One
{ public static void main(String[] args) 
  { Rectangle a = new Rectangle(5, 10, 20, 30); 
    System.out.println(a); 
    a.translate(15, 25); 
    System.out.println(a); 
  }
}
Put this in a file called One.java, compile and run.

As the notes say, your program won't compile. What's missing?

Fix the program, compile and run it.

Your output should look like this:

frilled.cs.indiana.edu%java One
java.awt.Rectangle[x=5,y=10,width=20,height=30]
java.awt.Rectangle[x=20,y=35,width=20,height=30]
frilled.cs.indiana.edu%
Did you obtain the same output?


9. (Also from lecture notes 3) Create a program:

import java.awt.Rectangle; 

public class Two 
{ public static void main(String[] args) 
  { Rectangle a = new Rectangle(5, 10, 20, 30); 
    Rectangle b = a; 
    a.translate(10, 10);
    b.translate(10, 10); 
    System.out.println(a);
  }
}
Place it into a file called Two.java, compile and run it.

I obtain the following output:

frilled.cs.indiana.edu%java Two
java.awt.Rectangle[x=25,y=30,width=20,height=30]
frilled.cs.indiana.edu%
What output do you obtain?

Now suppose that instead of printing a at the end we print b.

What would the output of the program be then, and why?


10. Check the documentation for class Rectangle and look up the intersection method.

The intersection method computes the intersection of two rectangles -- that is, the rectangle that is formed by two overlapping rectangles:

You call this method as follows:
Rectangle r3 = r1.intersection(r2);
Write a program that constructs two rectangle objects, prints them, and then prints their intersection. What happens when the two rectangles do not overlap?

(Note: this is problem P1.6 from the textbook).

When you are done check your solution against the program below:

/* Proposed solution for problem P1.6. Note that we test two
   cases, one in which the two rectangles overlap and one in
   which they don't. Read the documentation about rectangles
   with negative values for either width or height (or both)
   standing for empty sets. Note that a point is different
   from an empty set, even though it has no width or height
   it has a location. See the third test for that. 

   Bottom line is: is this correct or not? 

   Why, or why not? */ 

import java.awt.Rectangle;

public class Three {
    public static void main(String[] args) {
	Rectangle a = new Rectangle(0, 0, 10, 10); 
	Rectangle b = new Rectangle(5, 5, 10, 10); 
	Rectangle c = a.intersection(b); 
	System.out.println(a); 
	System.out.println("intersected with"); 
	System.out.println(b); 
	System.out.println("produces"); 
	System.out.println(c);   
        System.out.println("----------------------");  
 	Rectangle d = new Rectangle(10, 10, 10, 10); 
	Rectangle e = new Rectangle(50, 50, 50, 50); 
	Rectangle f = d.intersection(e); 
	System.out.println(d); 
	System.out.println("intersected with"); 
	System.out.println(e); 
	System.out.println("produces"); 
	System.out.println(f); 
        System.out.println("----------------------");  
	Rectangle g = new Rectangle(0, 0, 10, 10); 
	Rectangle h = new Rectangle(-10, -10, 10, 10); 
	Rectangle i = g.intersection(h); 
	System.out.println(g); 
	System.out.println("intersected with"); 
	System.out.println(h); 
	System.out.println("produces"); 
	System.out.println(i); 
        System.out.println("----------------------");  
    } 
}
What is the output that the program produces?

Use the program above or your solution to P1.6 to calculate the intersection of

  1. a square located at (0, 0) with a side of 10, and
  2. a square located at (-5, -5) with a side of 10.

Any square is also rectangle, so the two squares above can be created as follows

  1. new Rectangle(0, 0, 10, 10), and
  2. new Rectangle(-5, -5, 10, 10)

11. BigIntegers are like Rectangles, but they represent numbers.

Lecture notes 5 contain the following example:

import java.math.*;

public class Four
{ public static void main(String[] args)
  { BigInteger a = new BigInteger("100000000000000000000000000000000000000");
    BigInteger b = new BigInteger("200000000000000000000000000000000000000");
    BigInteger c = new BigInteger("300000000000000000000000000000000000000");
    BigInteger d = a.add(b.multiply(c)); 
    System.out.println(d); 
  }
}
Compile and run this program.

BigIntegers provide immutable arbitrary-precision arithmetic. That means numbers without limits. As big as you want. You will of course remember (from the very same lecture notes 5) that regular arithmetic has its limitation in Java. So one could use BigIntegers to avoid those limitations.

We will however use them to become familiar with object notation.

And to keep things simple let's use small numbers.

Here's how we calculate

1 + 2 * 3
The calculation is identical to the example presented before, only fewer 0's are present.

import java.math.*;

public class Four
{ public static void main(String[] args)
  { BigInteger a = new BigInteger("1");
    BigInteger b = new BigInteger("2");
    BigInteger c = new BigInteger("3");
    BigInteger d = a.add(b.multiply(c)); 
    System.out.println(d); 
  }
} 
Can you see how that's done?

Practice some more by using BigIntegers to calculate:


12. What is the output of this program?

public class Five {
    public static void main(String[] args) {
	String greeting = "Hello, Bill!"; 
        greeting.toLowerCase(); 
        System.out.println(greeting); 
    } 
} 
Please try to deduce the answer first.

Then run the program to double check your answer.


13. Modify just one line in the program above to obtain the following output:

HELLO, BILL!
You can only modify one line only.


14. The following program does not compile. Why?

public class Seven {
    public static void main(String[] args) {
	int one = 2; 
	int two = 3; 
        int two = two + one; 
	System.out.println(two); 
    } 
} 

15. The following program does not compile. Why?

public class Eight {
    public static void main(String[] args) {
	int n; 
        int m; 
        n = 2; 
        m = m + 2; 
	System.out.println(m); 
    } 
} 

16. Do you remember the Penguin() from lab assignment one? (I hope you do). Lecture notes seven define a class BankAccount (as does Chapter 3 in the book). A BankAccount is nothing but a Penguin (or a Tigger, for that matter). It has a number of things that it does best. (A ConsoleReader also has a number of things that it does best, and so do Rectangles, Strings, and even big numbers. We only need to know how to ask for them).

What do BankAccounts do best?

Well, we agree that a BankAccount must at least:

Any BankAccount rememebers its balance, and keeps track of it.

Here's a Java version of such a mechanism:

public class BankAccount
{ public void deposit(double amount)
  { balance = balance + amount; 
  }
  public void withdraw(double amount)
  { balance = balance - amount;    
  }
  public double getBalance() 
  { return balance; 
  }
  private double balance;
} 
We'll clarify what this means in lecture notes seven.

A second class, called Experiment, shows how one could use it.

public class Experiment 
{ public static void main(String[] args) 
  { BankAccount a = new BankAccount(); 
    BankAccount b = new BankAccount();   
    a.deposit(200); 
    b.deposit(300); 
    System.out.println(a.getBalance()); 
    System.out.println(b.getBalance()); 
    a.withdraw(100); 
    b.withdraw(200); 
    System.out.println(a.getBalance()); 
    System.out.println(b.getBalance()); 
  }
}
Create two files Place the code above in the corresponding files, then compile and run Experiment.

Explain the output.

Then write your own experiment, which simulates the following hypothetical sequence of events:


17. Now change the previous Experiment to allow the user to specify the amounts.

Make your program do this:


What comes next is your:

A201/A597 LAB ASSIGNMENT THREE

Next time you need to work, and prepare the following, to show to your AIs:

  1. Write the program Swap mentioned at Question 3.
  2. Write the program Reverse mentioned in Question 4.
  3. Write the MilitaryTime program as described at Question 6.
  4. Write a program that produces 5 random numbers between -8 and -3.
  5. Solve question 8 above, and be prepared to explain your solution.
  6. Solve questions 10, 11, 12, 13, 14, 15, 16, and 17 above.

As usual, this lab assignment is to be turned in next time (Jun 28) in lab.


Last updated: Jun 16, 2002 by Adrian German for A201