Program 1

Java Fundamentals + Objects

Introduction to Computer Science II
ICS-22


Introduction This programming assignment is designed to ensure that you know how to write "small" programs that use pre-written classes (either in the Java library, or by me). The constructors and methods for these classes are are documented in Javadoc (see the Javadoc of Sun's API and Javadoc of Course API links off the course web index), which you are expected to read during this assignment. It also requires that you know the standard control structures in Java, and will give you the opportunity to explore using the debugger on these programs. Finally, you'll practice writing, testing, and debugging programs using iterative-enhancement.

You will write three programs in this assignment. As always, you can check the behavior of your programs against mine by downloading and running my Executables, to help you understand the specification of the problem and observe the programmer/user interaction that you are to implement. The cardiac program includes various data files.

Write all your code in the main method of a class (the e program also asks you to write one static method. You will not need to write other methods or classes, nor code dealing with arrays (nor should you).

Because this assignment is straightforward, concentrate on using good programming style. Pay particularly close attention to the style principles discussed in the Coding Style lecture.

  • Names: Choose good names for variables.
  • Alignment: Indent statements to clarify the meaning of their control structures.
  • Locality: Keep related information together; separate unrelated information.
  • Comments: Document your code appropriately with comments.
You may also read items 5-14 and 25-26 in Vermeulen, The Elements of Java Style (which appear on pages 5-18 and 25-26). Please examine the Sample Programs that I have provided for examples of good programming style.

Write each program in its own project folder: you should name them accordingly (e.g., e, dicewar and cardiac); when you are finished with each, zip it and submit it via Checkmate. Each pair should submit one project: either partner can submit it. Of course, both partners names should appear in the comments of each program.

Carefully read the last two sections, on Extra Credit and Time Management. These important sections are relevant to all programming assignments, but appear only in this one.


e: a mathematical constant Write a program that approximates e by computing the exact rational (fraction) of N terms in its series. Using the infinite series, e = 1 + 1/1! + 1/2! + 1/3! + .... To compute this series to N terms we have e (to N terms) = 1 + 1/1! + 1/2! + 1/3! + ... 1/N!.

Your program must first prompt the user for N. It must also prompt the user to determine if the program's behavior is to be traced. The program then computes the numerator and denominator of the sum, using objects constructed from the BigInteger class. Ultimately the program prints the final approximation for numerator and denominator for e, and if tracing is turned on, all the intermediate numerators and denominators (such a facility is useful for debugging purposes, showing the intermediate values in a computation rather than just a final result). Here is a sample interaction

Enter N to compute approximation to e (using N terms): 5
Trace all sums(true): true
  e (approximated to 1 terms) = 2/1, which simplifies to 2/1
  e (approximated to 2 terms) = 5/2, which simplifies to 5/2
  e (approximated to 3 terms) = 32/12, which simplifies to 8/3
  e (approximated to 4 terms) = 195/72, which simplifies to 65/24
  e (approximated to 5 terms) = 7824/2880, which simplifies to 163/60
e (approximated to 5 terms) = 163/60
Run my executable with tracing (for small values N).

Here is a plan for writing this program via iterative-enhancement. First, write/test/debug a static method that computes factorial: its prototype should be BigInteger factorial (int). Second, prompt the user for N and whether to trace the code, and then write a loop that declares/initializes (and prints, if tracing is on) the numerator and denominator of each term in the series (1 and 1, 1 and 2, 1 and 6, 1 and 24, etc.) Third, declare and initialize the numerator and denominator of the sum, and update the sum during each iteration of the loop (printing each new sum if tracing is on). Note

     a     c     ad + bc
    --- + --- = ---------
     b     d       bd
Fourth, using the gcd method in the BigInteger class, simplify the result by factoring out the largest common term from the numerator and denominator. Finally, enhance your program to produce the exact output required.

Note I found BigInteger.ONE (check out this static final field in the BigInteger class in Javadoc) useful in a few places.


Dice War Write a program that simulates playing games of dice war; the program should also collect certain statistics while it is playing these games and report them after the required number of games have been played. In a game of dice war, each player starts out with his/her own dice (2, 6-sided) and some number (entered by the user) of chips. Each player roles his/her dice. If one player's pip sum is higher, that player gets a chip from the other player. Whenever one player has no chips left, the game is over (and that player has lost; and the other player has won).

Your program must prompt the user for the number of games to play, and the number of chips with which the players start each game. It must also prompt the user to determine if the program's behavior is to be traced. The program then simulates that many games of dice war, using object constructed from the DiceEnsemble class: one pair of dice for each player. It keeps track of the number of times each player wins, the length (number of dice rolls) of the shortest and longest games, and the total number of dice rolls (over all the games). It also uses a Timer to keep track of how long (in clock-time) it takes to play all the games. Try to use the DiceEnsemble objects themselves to keep track of some of the required information, so you do not have to declare extra variables.

Ultimately the program prints

  • how often each player won (it is a fair game, so these numbers should be about equal)
  • the length of the shortest and longest games
  • the total number of rolls (over all games)
  • the average number of rolls per game
  • the amount of time it took to simulate all the games
  • the simulation speed (number of games per second)
Finally, the program should also be capable of tracing its events. Such a facility is not used for long simulations, but instead it is very useful for short debugging runs. By tracing every important event in the simulation, we can display information useful for spotting bugs. When you build your program, you should trace the following events (if the user requests a trace)
  • starting a new game
  • playing one roll: indicate what each player rolled and how many chips each player has left after the roll (and redistribution of the chips).
  • winning a game
Run my executable with tracing (for a small number of games), with each person starting out with a few chips) and without tracing (for a large number of games) to observe all its behavior.

Here is a plan for writing this program via iterative-enhancement. Write a kernal program to prompt the user with the number of starting chips and then play one game. Second, add tracing to that game. Third, prompt the user for the number of games to play, and then play that many games (verify that it is correct via the tracing). Fourth, add code for keeping all the statistics. Fifth, add code for timing the game. Finally, enhance your program to produce the exact output required.

Explore the DiceEnsemble and Timer classes, and use them effectively to minimize the variables and code you must write. I found Integer.MAX_VALUE (check out this static final field in the Integer wrapper class in Javadoc) useful as an initialization for computing the smallest-length game.


Implantable Cardiac Defibrillators Write a program that simulates the working of an Implantable Cardiac Defibrillator (ICD). An ICD is a small electronic device placed in the chest cavity of a patient who is suffering from arrhythmias (heartbeat irregularities). This device constantly monitors the electrical output of a beating heart: if it detects a bradycardia (heart beating too slowly) it acts a pacemaker; more importantly, if it detects a tachycardia (heart beating too fast to pump blood effectively: in extreme cases this results in ventricular fibrillation) at which point it acts as a defibrillator by supplying a large shock to the heart in an attempt to restore a normal rhythm. This shock is described by patients as feeling like a kick in the chest -although many patients are unconscious by the time action is taken on the detected arrhythmia. If you are interested, you can read more detailed information on ICDs.

The basic algorithm inside an ICD computes the zero-crossing count (ZCC) of the electical signals it samples while it is monitoring a heart. Each signal should be between the value of -100 and +100 inclusive (if not, the ICD is receiving faulty signals, and it should shut itself off). During an interval (typically lasting a few seconds), whenever the signal value goes from positive to negative or negative to positive, the ICD increments its ZCC. For the purposes of this assignment, we will treat 0 as a positive number. At the end of an interval, the ICD checks to see whether its ZCC is within a normal range: in a bradycardia the ZCC is too low (equals or falls below some threshold); in a tachycardia the ZCC is to high (equals or exceeds some threshold). If the ICD detects either of these conditions it takes the necessary action; then it resets the ZCC and samples the heart signals for another interval. Of course, real ICDs have evolved to exhibit much more sophisticated behaviors.

For example, if the ICD is using an interval length of 10, the following table labels each sample, shows the signal value for that sample, and the current ZCC.

Sample# 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...
Signal  0  5 10  5 -5  5 10  5 -5 -5  5 10  5 -5  5 -5 10  5 -5  5  5 10 ...
ZCC     0  0  0  0  1  2  2  2  3  3  1  1  1  2  3  4  5  5  6  7  0  0 ... 
ZCC reset to 0----------------------^-----------------------------^----- ...
For example, between sample #4 and #5, the signal goes from 5 to -5 so the ZCC is incremented. The ZCC at sample #10 (the end of the first interval) is 3 (after which it is reset to 0 but immediately incremented to 1 because between sample #10 and #11 the signal goes from 5 to -5); at the end of the second interval it has risen to 7.

This program will simulate the simple ICD algorithmg, allowing us to test it on various data files that represent samples taken of the actual electrical signals of a monitored heart. It should operate as follows

  • Prompt the user for the name of the ICD's configuration data file (input), and the name of the simulated heart data file to monitor (input).
    The configuration file specifies three values: an example would look like 100 15 25:
    • The interval length: how many signals to read from the data file while computing each ZCC; after these many signals, the ICD decides if the heart is arrythmic and resets the ZCC. It continues reading more signals, deciding whether or not the heart is arrythmic every interval length.
    • The bradycardia threshold: if the ZCCs in a an interval equals or falls below this threshold, the heart is beating too slowly.
    • The tachycardia threshold: if the ZCCs in an interval equlas or exceeds this threshold, the heart is beating too quickly.
    The simulated heart file contains a sequence of electical signals that the ICD should process.
  • Display on the console the information extracted from the configuration file; if these three values cannot be read correctly (see the badconfig.txt file), the program should terminate.
  • Simulate the action of the ICD: read signals from the simulated heart file and compute the ZCC for each interval; display the ZCC for that interval, along with any action to take if the ZCC indicates an abnormally beating heart.
  • Continue this process until
    • There is no more data in the simulated heart file
    • A bad signal value is read: smaller than -100 or greater than +100
Before starting to write your program, run my exectable on all the different data files that I've supplied (in the inputs folder), to familiarize youself with its operations, output messages, etc. Then, follow the iterative enhancement approach when writing this program. It is an excellent idea to add comments as you are writing the code, to help you understand it while you are enhancing it. Initially, test you enhancements on the initconfig.txt and initheart.txt data files (they use the data illustrated above, and test everything but a bad signal: to do so, modify initheart.txt by replacing any value first by -500 and then +500 in this file).
  1. Write a kernel program that prompts the user for the name of the configuration file, reads all the data that it contains, and then displays it on the console.

  2. Enhance the program so that it also prompts the user for the name of the heart data file too, reads and displays every value in this file (prefaced by the sample number: 1 for the first signal, 2 for the next, etc.), terminating the program when it unsuccessfully tries to read a data value from the file (e.g., it tries to read a non-integer value or it tries to read another value when there is none). Hint: this is the only loop that your program needs, and it should include a try-catch statement that handles any exception by terminating and printing a message.

  3. Enhance the program so that it also terminates the loop if the signal value is not between -100 and 100 inclusive.

  4. Enhance the program so that it displays on the console the message Make Decision after reading enough sample signals to fill the interval. For example, if the interval is 10 samples, the ICD should read and display the first 10 signals (numbered 1 through 10) and then display Make Decision; then it should read and display the second 10 signals (numbered 11 through 20) and then display Make Decision again, etc.

  5. Enhance the program so that it computes and displays the ZCC after it read each value from the heart data file. This change will require two variables: one storing the value of the previous signal and one storing the value of the current signal; the current value becomes the previous one at the end of each loop iteration. Initially (before the loop even starts), set the previous value to 0. Each iteration of the loop reads a new value for current from the heart input file.

    Also change the Make Decision message to display the current ZCC (whose value it will actually use to check for bradycardia or tachycardia). Important: after each decision is made, the ICD should reset the ZCC to 0, as it begins computing the ZCC for the next interval of signals.

    When you have verified that the right ZCC values appear in these messages, remove the code that displays each signal, and the ZCC for each new signal read.

  6. Enhance the program to display Bradycardia Detected if the ZCC equals or falls below the threshold read from the configuration file, and display Tachycardia Detected if the ZCC equals or exceeds the threshold read from the configuration file.

Boiler Plate Comment Start each of your files with a comment like this one.
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// Program        : Craps Statistics
//
// Author         : Richard E. Pattis
//                  Computer Science Department
//                  School of Information and Computer Science
//                  University of California at Irvine
//                  Irvine, CA 92617-3435
//                  e-mail: pattis@ics.uci.edu
//
// Maintainer     : Author
//
//
// Description:
//
//   Craps prompts the user to enter the number of games to play. It then
// plays (simulates) that many games of craps, keeping the win/loss
// information. At the end, it displays these statistics.
//
//   Craps is a dice game. The thrower loses if he/she immediately rolls a 2
// (snake eyes), 3, or 12 (box cars). The thrower wins if he/she immediately
// rolls a 7 or 11. If the thrower does not immediately win or lose, the number
// thrown becomes the "point". Afterwards, the thrower tries to make his/her
// point by rolling that same value again (and winning) before rolling a 7
// (and losing). When trying to make his/her point, the thrower keeps rolling
// if he/she rolls any number other than the point or 7.
//
//   This version of Craps Statistics uses the DiceEnsemble and Timer classes
// to create objects that reduce the complexity of the code while increasing
// the information it computes. Note that because dice.roll() returns the
// dice ensemble, we can write the single declaration
//   int roll = dice.roll().getPipSum();
// instead of having to write two statements (if dice.roll() was null)
//   dice.roll();
//   int roll = dice.getPipSum();
//
// Known Bugs     : None
//
// Future Plans   : None
//
// Program History:
//   8/ 8/00: R. Pattis - Operational in C++
//   5/15/01: R. Pattis - Translated to Java
//   5/16/01: R. Pattis - Changed identifiers to conform to Java style
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

Extra Credit Programming assignments must be turned in on time: you can get partial credit for a partially completed assignment, but it must be turned in on time; I will accept no late homework unless you have an official excuse (and it is best contact me as soon as the problem arises, not after the due date). In fact, there is another incentive to finish not only on time, but to finish early.

In all programming assignments, if you turn in everything at least 24 hours before it is officialy due, you will receive 2 point of extra credit. If you turn it in 48 hours (or earlier), you will receive 4 points of extra credit. (There is no more extra credit for early turn-ins; I recommend NOT turning it in more than 48 hours early -specifically, wait until you receive your graded previous program before turning in a new one). This is equivalent to almost one full grade improvement on a 50 point programming assignment. In previous quarters that I have taught, almost 75% of the students completed their assignments early and received some amount of extra credit

There are two main advantages to planning on finishing early. First, if you run into a major problem, you will have extra time to solve it before the actual due date: and even experienced programmers frequently run into such problems. Yes, this means you! Second, and more importantly, if you are racing to finish before a deadline, stress levels can go through the roof, and you become less interested in learning the material (and the whole purpose of these programming assignments is to learn the material) and more interested in just getting it finished. If you do not learn the material, you will be at a major disadvantage for all subsequent programming assignments and tests, because of the cumulative nature of the material in this course. Therefore, plan to finish every assignment by Tuesday or Wednesday evening.

Programming assignments sometimes also include an extra credit section worth 1-2 points. These are designed for students who finish early and want to continue exploring programming within the context of the assignment. The points are to acknowledge, in a small way, their extra effort.

The dice war problem has 1 point of extra credit. To earn it, at the bottom of the main comment, include a section labelled Extra Credit. In this section, estimate the average number of dice rolls for a game where each player starts out with 1,000,000 chips. Explain the details of how you arrived at your estimate.

Do not discuss your estimate with anyone but the student you are pairing with.


Time Management One of the hardest parts of being in college is learning how to manage your time. Time management is especially important in programming courses (and in the real world, when you are working on complicated projects with hard deadlines). The difference between good and bad time management can have a profound impact on how much you learn in this course, how well you perform in it, and how much effort you actually need to expend to do well.

I will try to divide most programming assignments into a series of smaller tasks, each that can serve as a milestone; when solved in sequence, these tasks will complete the entire assignment. We will discuss such a divide and conquer method more formally, calling it iterative enhancement.

Generally, it is best to spread out the work on a week-long assignment. Most assignemnts become available on Wednesday in lab; we will overview the assignment in lab and you will start working on one aspect of it then as well; assignments include executable files, so you can see how the program should behave (including its input and output -which you must match). We can discuss the assignments in lecture on Thursday, before the weekend. You should plan to complete at least half the programming assignment over the weekend, and then plan to finish the rest early in the week (by Tuesday or Wednesday, to get any extra credit).

Some students look at an assignment and think that it is best done in one sitting. If you can do so, great; but, if you plan to work this way, do the one sitting over the weekend, not Thursday night! In this way, if you are wrong about the amount of time that it will take, you will still have adequate time to complete the assignment. By meeting these time goals, you will both maximize what you learn and minimize your anxiety and the time that it takes for you to do the learning.

Remember that assignments must be turned in on time: you can get partial credit for a partially completed assignment, but it must be turned in on time; I will not accept any late homework unless you have an official excuse.

Finally, if you find yourself falling behind, seek help immediately (from me, the CAs, or even other students in the course -when appropriate). When the real programs start, we will discuss what kind of help you can get legitimately, and what kind of help constitutes cheating.