2012-2013 ICS3U SOFTWARE ENGINEERING TASKS

TASK 'CHALLENGE' RATING (offered to assist you with project management strategies)
Routine
Typically some deep thinking required, but not necessarily a lot of coding.
Hard
Likely involves either a multiplicity of new concepts and/or new mathematical concepts or algorithms.
Really Hard
Start immediately, think hard, employ a stepwise refinement strategy and post concerns as required.

The Game of Life 2. As a permanent reminder of your recent coding of the Game of Life, you will revisit your Evil Genius soldering skills by assembling the Game of Life v1.3 Kit from Adafruit.

Follow the tutorial carefully throughout the week and leave your working system on my desk before you leave this Friday.


The Game of Life. John Conway introduced the world to one of the most studied algorithms within the Cellular Automata family in the October 1970 issue of Scientific American. Read Wikipedia's explanation of the simple rules for propagation. Explore the game through either or both of the Explore links on the course page. Give yourself time to enjoy how such an elegantly simple set of rules can produce such fascinating outcomes. In the applet to the right, I have colour-coded the cells as Birth (green), Survival (red) and Death (black), with Empty cells remaining in the background colour (white) to enable you to better track the evolution of the popluation. Numerous web sites will offer code for the Game of Life so you are asked to stick to my specification.

Our Life board is 'played' on a matrix with a base type of Status, an enumerated type. The constants defined within Status will help maintain the precise state of each cell from one generation to the next and help with colour-coding. To ensure ALL cells in the board have exactly 8 neighbours, the border cells on all four sides will maintain the EMPTY status throughout the generations. For the time being, the inital population will be randomly created, using the value of the probability field to assist with the initial population density.

Task.

  1. Create the project GameOfLife that will function both as a standalone application or as an applet.
  2. Examine the project's UML diagram below. You will recognize it's structural similarity to our recent RandomWalkTest project.

  3. After considering the rules for birth, death and survival implement the class and method designs above as efficicently as possible.
  4. (After Life) Add menu items that include one or more random seeds and a library of a handful of known patterns that you find inspiring. Glider Guns, Puffer Trains, and Tire Tracks are my favorites.


Random Walk. The objective of this in-class task is to establish a platform for graphic animation based on threads. This template will provide a foundation for the remaining assignments in this course.

Task.

  1. Create a project entitled RandomWalkTest and drop in a driver by the same name.
  2. Implement the structure of the UML diagrams below for the RandomWalkTest driver class and the RandomWalk class so that the project compiles
  3. Group discussion will enable you to complete the bodies of the methods. Here's what we're going for: RandomWalkTest.jar

  4. RandomWalkApplet. It's time to add dual functionality to your project in which the code can be run as an application or as an applet.
  5. Your F/C Web Site. Follow the steps presented in class to create your web presence using the web Server facilities of First Class.
  6. RandomWalkAppletCumulative. Rather than simply moving the cell we need to leave a trail to see visualize the path taken. TBC.

Image Processing. The objective of this in-class task is to appreciate that an understanding of Java's file- and graphics-handling classes can be used to develop some useful image processing utilities.

  1. After reviewing the short tutorial on How To Resize an Image in Java create a Project entitled ImageProcessing and add a driver by the same name.
  2. Display the results of the Google search for RSGC cdarcy and save the Web Page in your ImageProcessing folder under the name of images.
  3. As you can see by looking within the image_files folder that, although there are files of different types, Google saved all the images as .jpg despite the original images being of different types (.gif, .png, etc.)
  4. Your task is to implement code within your ImageProcessing class to convert all the .jpgs to thumbnail size (dimension 100px × 100px) and saved under a new filename that consists of the String 'Resized -' prepended to the original filename.

Recursive Folder Display. As you are aware, a file within a folder can, itself, be a folder. This a naturally recursive pattern! Your previous experience with recursion will enable you to experience the reward of applying your skill to the task of displaying the full listing of the files within a given folder, complete with an indication of depth, much like the Package Explorer sidebar within Eclipse itself.

  1. Within your OpEnvOps.java driver file, comment out all the statements in the main method. Do not delete them.
  2. Add a method call in the main method to the non-recursive method, displayFolder().
  3. The displayFolder() method is responsible for soliciting a path from the user through the use of JOptionPane's showInputDialog() method, the input from which it will construct a new File object, prior to making a call to the recursive helper method, displayListing(folder, 0).
  4. The public static void displayListing(File folder, int n) method is responsible for a recursive traversal of folder, displaying the names of all folders and files it encounters while doing so. The parameter n reflects the depth of any file's entry. Starting at a depth of 0 for the root of the search, every time a folder is encountered the depth increases by 1, naturally. When all the files within a folder have been displayed, the method terminates and returns to where it was called returning n to is previous value. You are free to interpret the value of n any way you want in displaying the file names (spaces, tabs, etc). In the screen capture below, I simply indented a single space. Rollover my listing to see the actual listing of the files as my OS presents it.
  5. Be sure to examine all available resources within Java's File class. Note. Java, like Windows, refers to a folder as a directory.

 


Sorts. The search for a fast, efficient sorting utility has led to the development of numerous algorithms. Some techniques are easy to understand and code, but can execute relatively slowly. Others are extremely fast, but challenging to understand and maintain. In this assignment, you are asked to compare (time) the speed of four popular algorithms (Selection, Insertion, Mergesort and Quicksort). We've developed original code for the first three in class and we implemented the Quicksort from the pseudocode.

Task.

Minor modifications to your SortingAlgorithms code developed in class can be made to produce a tabular comparison of the four algorithms as measured against the same data in a single run. A sample run on my computer yields the results above right (2.4GHz P4). For optimum results you should close all other running processes. For convenience, the code writes the timing results in an Excel-convenient format (space for columns, \n for rows).

Identify the speed of the processor used for your results on the worksheet. Provide an appropriately-labeled graph of the timing results on a separate, full page worksheet, appropriately renamed. Submit both documented SortingAlgorithms.java and Sorts.xls files to handin by the deadline.


(Recursive) Reversal. This past week you were introduced to the concept of recursion as a problem-solving and programming strategy. This exercise will give you another chance to put this technique to work. The task is to develop a method that reverses a String.

Task.

  1. Drop the driver file Reverse.java into the Recursion project you created this week.
  2. Your task is to complete Line 35, only. Do not add any more statements, simply complete the return statement that results in the reverse String of the parameter being returned. Here's the sample output,

 


BINGO! This three-part assignment is designed to solidify your array and Arraylist<E> skills.

Bingo1: Bingo Card. Create a project called Bingo1 and add this driver. As you can see, the driver simply instantiates and displays an instance of a BingoCard class. Provide an implementation of the BingoCard class that follows this basic UML design. You output should look similar to the capture below.

 

Bingo2: Bingo Player. In this stage you will simulate a single-player Bingo Game. A player has a name and can have as many cards as he chooses. The driver loads the 75 possible calls (B1 to O75) into an array and then randomizes the array. The driver loops through the calls and the player marks an X on each card that matches the call. Before returning for the next call, the driver calls the player's isWinner() method that, in turn, calls each of his/her card's isWinner() method to determine whether any of the player's cards is a winner (12 ways per card). If there is a winner, play stops and the total number of calls is displayed, together with the state of EACH of the player's cards for visual verification.

Task. Create a new project entitled, Bingo2 and drop in this driver. Configure Bingo2's Build Path by adding the Project Bingo1 so you only have one version of the BingoCard class. Following this UML diagram, create a BingoPlayer class and implement the enhancements to your BingoCard class. Sample output appears to the right.

Attach Bingo2.java, BingoPlayer.java and BingoCard.java files to an email to handin under the Subject Line: Bingo2.

Bingo3. Bingo Game. The final stage of out Bingo Trilogy should be obvious. You are to simulate a multi-player Bingo Game. In the past few lessons you have been introduced to Java's ArrayList<E> class that offers users a suite of methods for the convenient manipulation of arrays. So, just as the Integer and Double classes are wrapper classes for ints and doubles respectively, the ArrayList<E> class can be thought of as a wrapper for arrays.

Task. Create a project called Bingo3. Configure Bingo3's Build Path to include your Bingo1 and Bingo2 Projects. Add the text file Players1213.txt to the Bingo3's root folder. Examine the contents of the file. The data file has a number of records that contain two fields each (the player's name and number of cards), separated by a tab. Using much of Bingo2's driver code, create the driver for Bingo3 that populates an ArrayList<BingoPlayer> container with the data from Players1213.txt. Then, undertake a Bingo game in which all players (and all their cards!) participate until a winner is identified. For verification, print out ONLY the winning player(s) and all of his cards. Note: I will use a different Players1213.txt file (with the same field structure) when I evaluate your project.


The Sieve of Eratosthenes. There is no known efficient procedure for finding prime numbers. A classical, but tedious, method attributed to Eratosthenes (276 - 196 BC), can be described as follows. First, write down a list of integers, paired with true values,

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
T T T T T T T T  T  T  T  T  T  T  T  T  T  T  T

Then mark all multiples of 2 by switching its true to false,

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

T T F T F T F T F T F T F T F T T T F

Move to the next unmarked number, which in this case is 3, then mark all its multiples:

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
T T F T F T F F  F  T  F  T  F  F  F  T  F  T  F 

Continue in this fashion, marking all multiples of the next unmarked number until there are no new unmarked numbers. The numbers which survive this marking process (the Sieve of Eratosthenses) are primes.

Task. Write the class, Sieve, that will implement the Sieve of Eratosthenes and determine the prime numbers from 2 to n-1, where the integer n is determined by the user. 

Your program will create an array of length n, initializing all cells to true. Starting with array index 2, (ignore index 0 and index 1), every time an array element is found to be true, loop through the remainder of the array and set to false every element whose index is a multiple of the starting index.

At the end of the implementation, array elements that remain true have an index which is a prime number. Display the prime numbers to the console.


Binomial Theorem. A deep understanding of the Binomial Theorem will prove useful to you in the months and years ahead. In this project you'll undertake a two-part computational investigation of the Binomial Theorem. Here's a reasonably compact definition of the Binomial Theorem,
(BT-1)

Application of (1) yields familiar binomial expansions,
(BT-2)

Part 1. Combinatorics. Consider the following definition from the field of Combinatorics,
(BT-3)

The left side of (3) is read as n choose r and represents the number of combinations of n distinct items one can make, choosing r of them at a time (the last two expressions in BT-3 are different ways of expressing the same concept). As can be seen, the determination of this integer result relies on factorials. For example, assume 5 students show up for class and I need to choose 2 students to go down to Bloor and pickup the sushi order we placed for lunch. How many ways can the pair of students be chosen? There are 10 such combinations determined as follows,
(BT-4)

  1. Create a project called, BinomialTheorem that exercises the new methods in your static NumericalMethods class.
  2. /***************************************************************************
    * This method determines the value of n!                                   *
    * Precondition: n>=0                                                       *
    * Postcondition: the method returns the value of n!                        *
    * @param n the whole number for which the factorial is to be determined    *
    ****************************************************************************
    public static int factorial(int n)
    
    /****************************************************************************
    * This method returns the number of combinations that can be expected given *
    * n items, taken r at a time. This does not need to be recursive.           *
    * Precondition: n>=0, 0<=r<=n                                               *
    * Postcondition: the method returns the value of nCr                        *
    * @param n the number of items from which combinations are taken, n>=0      *
    * @param r the number of items taken, 0<=r<=n                               *
    *****************************************************************************
    public static int choose(int n, int r)
    
    
  3. Now you will display Pascal's Triangle. Add the method below to your BinomialTheorem driver,
    /**********************************************************************
    * This  method displays a number of rows of Pascal's Triangle         *
    * Precondition: rows>=0 * * Postcondition: the method displays the requested number of rows of * * Pascal's Triangle. It relies on the choose method * * @param rows the number of rows to be displayed * *********************************************************************** public static void pascalsTriangle(int rows)

Part 2. Binomial Expansion. To complete this year's look at the Binomial Theorem, perform the following,

  1. Add the driver BinomialTheorem2 to your project and examine its contents. To keep things simple, use only variables for the terms in the binomial and limit n to values safely handled by your factorial method.
  2. Add the following two methods to your static NumericalMethods class and implement the bodies of the methods so that the project yields the output presented in Step 3.
    /***************************************************************************
    * This method returns the String representation of the r'th term of the    *
    * Binomial Theorem of (a+b)^n                                              *
    * Precondition: a, b the String equivalents of the binomial's terms        *
    *	              n>=0, 0<=r<=n                                        *
    * Postcondition:the method returns the String representation of the r'th   *
    *	              term of the expansion of (a+b)^n.                    *
    * @param a the first term in the binomial (a+b)                            *
    * @param b the second term in the binomial (a+b)                           *
    * @param n the degree of the binomial expansion                            *
    * @param r the required term in the binomial expansion, 0<=r<=n            *
    ****************************************************************************
    public static String binomialTerm (String a, String b, int n, int r)
    
    
    /***************************************************************************
    * This method returns the full binomial expansion of (a+b)^n as a String   *
    * Precondition: a, b the String equivalents of the binomial's terms, n>=0  *
    * Postcondition:the method returns the String representation of the        *
    *                expansion of (a+b)^n                                      *
    * @param a the first term in the binomial (a+b)                            *
    * @param b the second term in the binomial (a+b)                           *
    * @param n the degree of the binomial expansion                            *
    ****************************************************************************
    public static String binomialExpansion (String a, String b, int n)
      
  3. Execute the project so that it results in the following output,


Trigonometric Functions. The Math class offers a wide variety of mathematical tools for use by clients. (the trigonometric functions are members of a class of functions known as transcendentals in that the exact value can't be computed precisely, but rather is approximated, typically through the addition of successive terms in a well-defined series)

Degrees (d) to Radians (r). The Math class offers two built-in conversion methods, toDegrees(double angrad) and toRadians(double angdeg) for your convenience that implement the following definitions,

Infinite Series Approximations of the trigonometric functions sin(x) and cos(x), x in R (radians)

Task.

  1. Create a new project called Trigonometry and drop in this driver.
  2. To your NumericalMethods class, add implementations for the following two methods,
    		public static double sin(double angle)

    and

    		public static double cos(double angle)

    based on the two series above that can be used to confirm the accuracy of the built-in methods of the Math class. If your NumericalMethods class works properly, the project will yield the output below (up to 45°, inclusive).

  3. The formulas above suggest another static support method that would be useful.

  4. Enhance the driver by adding two columns for tan(x). The first of the two new columns draws on the Math class and the second of the new columns combines values from your NumericalMethods class.
Submit your enhanced Trigonometry.java driver and NumericalMethods.java classes by the deadline.


Project Euler: Problem 12.
One Star Exercises. (Since some of you are struggling to complete the single weekly challenging assignments, we'll take a different tact this week to see if we can restore some confidence and prep for next Tuesday's test at the same time.)

Pages 222-223 contain eight Programming Exercises considered easy by the author (ExP15_4, ExP15_5, and so on). You are to do them all. Attach fully documented sources files, correctly named, to an email to handin with the Subject: One Star Exercises, by the deadline. I will evaluate one of them at random.


Line. At this point in your development, it is no longer sufficient to produce code that simply works, you have to think deeply about the exercise, use the appropriate tools, and code in justifiable efficiencies. Consider Exercise P5.15 on page 224, henceforth known as, LineTest. Using this LineTest.java driver, develop the UML diagram as the file Line.uxf and implement the Line class as required to produce this output. Attach Line.java and Line.uxf to an email with the requested Subject Line to handin by the deadline.

iTunes1. To gain familiarity with boolean operators and expressions, we'll query a database (text file) for data that match specific criteria.

Task.

  1. Create a project entitled iTunes1, a driver by the same name, and add the text file Music1.txt to the root folder of the project. This file (database table) contains over 500 records for which 8 fields are offered (Title, Artist, Composer, Album, Genre, Size, Time & Year). Fields are separated by a tab character.
  2. Read access to a text file can be established as follows (see pp. 498-500 if you're interested),

    Add the above code to the main method of your iTunes1 driver.
  3. Using your Scanner object, read in the first line of text in the file and display it to the Console Window.
  4. Write a conditional loop around a call to your Scanner object's nextLine() method to read in each record of the database and a System.out.print statement to display the each record to the Console Window.
  5. Inside the loop, split each record of the database into an array defined by String fields[] to enable you to identify records that match various criteria.

Now, construct boolean queries to determine the number of matches for each of the stated criteria below. (Note: You many wish to open Music1.txt in Excel to confirm the data sets your queries produce)

  1. Display the number of tracks whose Title field starts with the word, You.
  2. Display the number of tracks whose Title field includes the word You or you in any position.
  3. Display the number of tracks from 1967.
  4. Display the entire record for any track from the 60s. Display the number of tracks at the end.
  5. Display all tracks by the The Beatles not composed by George Harrison or Ringo Starr that are less than two minutes. Display the number of tracks at the end.
  6. Display all Pop or Rock tracks that are over 5 MB. Display the number of tracks at the end.

Table 1. Each Guess
Table 2. Honour
Guess
Result
Number of Guesses
Level
exactly
Bingo!!
1
Jedi
within 1
Hot!
2
L337
within 2
Warm
3
Peasant
otherwise
Cold
otherwise
n00b
Oracle. We examined a strategy that could be used to test for the virtual equality of doubles to avoid problems associated with roundoff error. Although we'll be using ints in this assignment, you'll construct a similar test to evaluate your users' powers of deductive reasoning. Your Oracle object (see UML diagram) will randomly (Random or Math class) generate an integer over the closed interval [0, 9] and keep it secret. In your driver, OracleTest, you will instantiate an Oracle object and subsequently ask the user to submit up to three guesses. Using strategic Oracle method calls within if...else ladders (no loops!) take the user through the guessing game and label him according to Table 2.

Task. You are to give the user no more than three attempts to discover the secret digit. Summarize each game by labeling the player's outcome according to Table 2. In addition to printing the label, also display the secret number for confirmation purposes (not before as in the two examples). Use as many elements of good coding conventions and style that we have discussed and submit OracleTest.java and Oracle.java to handin by the deadline.

 

 


Comparing Objects: Prioritizer. (In class) You are aware that the equality operator (==) is not used to compare the values of two objects. The preferred technique is to add the method, public int compareTo(Object other)to any class that requires a signed integer ranking between the implicit parameter (this) and the explicit parameter (other) instances of the class.

To assist in the prioritization of assignments that require completion, you are to develop software to tell you what your highest priority task is.

  1. Create a project called Prioritizer, drop in the driver Prioritizer.java, and review the code. The WorkLoad class maintains an array of Assignment objects. The Assignment class encapsulates information about an individual assignment that includes its name, completion time, worth, and diamond rating (difficulty).
  2. Implement the code for the WorkLoad and Assignment classes using the UMLs below as a template.
  3. For now, Assignment's compareTo method should return the integer value based on the worth instance field.
  4. Use the String.format() method in Assignment's toString() method to assemble a formatted String similar to the output shown below.


IP Address. (This assignment will give you practice manipulating numerical and String data in the analysis of an Internet Protocol (IP) address) The purpose of this assignment is to allow the user to enter an IPv4 address in dotted-decimal form and the software will convert it to it's binary equivalent (if it is valid). You can restrict the reasons for an invalid address to either an incorrect number of octets (there should be exactly 4) or the value of any given octet is out of range (it must be between 0 and 255, inclusive). Take a test drive of the final project. In addition, you are encouraged to look carefully and the driver's use of JOptionPane's input and output dialog boxes. Use these dialogs where appropriate in the assignments ahead.

Task.

  1. Read Wikipedia's article on the structure of the IP address. We'll restrict ourselves to the IPv4 protocol for this assignment. Click here for your IP address.
  2. Create a project called IPAddressTest and drop in this driver. Review the driver thoroughly for both the javadoc and the handling of the Dialogs. For those that are interested more information on Dialogs can be found here.
  3. Create the class IPv4 that models the UML diagram to the right.
  4. Develop the code necessary to have your project function similarly to the example.
  5. Once completed, mount an executable jar version of your project on your web site.
  6. Finally, submit the fully javadoced IPv4 source file to handin by the deadline.

Newtons' Method for (Square) Root Finding. There is no (easy) direct computation of the square root of a non-negative real number. However, numerous algorithms exist for determining an approximation to it. One useful algorithm, sometimes referred to as Newton's Method, can be described as follows.

Suppose the goal is to determine the square root of 20, call it x. Since 16<20<25, we know the answers lies somewhere between 4 and 5, likely closer to 4. In some situations, we could stop here, offering 4 as the square root of 20. But, like any good competition, a better approximation would be impressive. Try this. If we let x=4, Newton suggested,

would result in an improved approximation. A quick calculation yields a result of 4.5. Squaring 4.5 produces 20.25. Not bad. Newton's prediction appears to be correct. Ok, from 4 we calculated 4.5. Is this the end of it? Is this the best approximation we can come up with?

Task. Create a project called NewtonTest and drop in this driver. Next, create a static NumericalMethods class and implement (at least) the following two methods,

/**
* sqrt returns an approximation to the square root of the number a,
* given an initial guess of x, using n iterations of Newton's Method
* @param a the radicand
* @param x the initial approximation to the square root of a
* @param n the number of iterations of Newton's Method
*/
public static double sqrt(double a, double x, int n)

and

/**
* sqrt returns THE BEST approximation to the square root of the number a,
* given an initial guess of x, using Newton's Method
* @param a the radicand
* @param x the initial approximation to the square root of a
*/
public static double sqrt(double a, double x)

Your code should yield the output below. Submit your NumericalMethods class by the deadline.


Exercise P5.2. Using the UMLet drawing utility, develop an appropriate UML diagram for the Card class and save it as Card.uxf. Create the project ExP5_2 and add a driver by the same name that accepts user input from the Console window with the help of the Scanner class. The driver processes the input as required and delivers output similar to the sample provided by the problem specification.


Name. The dual purpose of this project is to deepen your understanding of methods in the String and the Scanner classes.

Task.

  1. Run the executable jar: NameTester.
  2. You can see by the example, that the name of person has been inverted by taking the surname and appending the first and second initial (as well as spaces and periods).
  3. Develop the class Name based on the adjacent UML diagram.
  4. For your driver class, NameTester, whereas I have used JOptionPane methods to handle the I/O (for illustrative purposes), you are asked to use the Scanner class for user input from the Console window and the System.out class for Console output. Note: all three names of the person are to be entered and read in at the same time.
  5. Here is a list of famous people with three names.
  6. Document and submit both NameTester.java and Name.java by the deadline.

Toyota Logo Revisited. In preparation for next week's larger graphics application, you are asked to make a few improvements to your previous Toyota application.

Positioning and Proportion Improvements.

  1. Ellipses. When the window is resized, your logo should adjust accordingly, maintaining its proportionality and its centered position with the frame. Recalling that every JComponent's paintComponent(Graphics g) method is called by the Java Virtual Machine (JVM) when itis ready to have the panel updated, you must include code to obtain the new dimensions of the panel every time. JComponent's getSize() method returns a Dimension object that can be mined for the active width and height of the drawing area, as in,
    Dimension dim = getSize();
    
    Determining the coordinates of the center of the panel is simply a matter of averaging the two measures, while accounting for the height of the title bar. With the center known, constructing the rectangular bounding areas of the three ellipses is straightforward. The only concern you have is allowing enough room at the bottom for the TOYOTA name.
  2. Text. Again, when the window is resized, the TOYOTA text must be dead center underneath the ellipses. In your previous attempt, most students simply used trial and error to guess what the position of the text should be. As you will see, once you have the ellipses dynamically repositioning and resizing themselves, a static position and font size for the text is inadequate. The good news is that every chunk of graphics text has a bounding rectangle. The key, then, to properly positioning graphics text is not unlike manipulating any rectangle.

    The FontMetrics class of java.awt encapsulates information about the measure (metric) of a given font. Coincidentally, the Graphics2D class has method called getFontMetrics() that returns a FontMetric object that can be manipulated to reveal the bounds of a given String object within the current graphics environment in the form of a Rectangle2D object.

Task. By the deadline, remount your (improved) Toyota.jar application on your website and submit your source code to handin.

Toyota Logo. For your first Java2D graphics assignment you are asked to recreate the familiar logo. Create a graphical application called Toyota that renders the logo to the right as closely as you can. Some of the areas you will need to investigate include,

Note. An important consideration is the scalability of your rendering. As can be seen from this example, as the frame is resized, the image remains proportional, centered horizontally and scaled to ensure it remains entirely within the panel.


Project Euler: Register. You are asked to create an account with Project Euler and send me an email to handin that contains your Username and Password (I will use this information over the course of the year to monitor your progress). Optional: Try to complete one problem (any problem) by Saturday deadline.

Project 4.1. Consider Project 4.1 as specified on pp. 179-180.

  1. Using a Stepwise Refinement approach, develop a UML diagram for the Triangle class. Consider all necessary instance fields and methods.
  2. Create a Java Project called, Project4_1.
  3. Add a driver class by the same name to the Project. Within the main method, instantiate an object of the Triangle class.
  4. Add a Triangle class to the Project and implement instance fields and method stubs as required by your UML diagram so that the Project compiles without exceptions. Incorporate appropriate commenting as you go.
  5. Undertake the implementation of the method bodies, starting with Triangle's constructor.
  6. Develop a variety of well-thought out test cases to fully exercise your Triangle class. Be sure to examine the output carefully (don't simply assume the results are correct)