Lab 3
Goals: The goals of this lab is to work with complex information: practice designing self-referential class hierarchies and designing methods for them.
For this lab, there are no starter flies. For each problem, start a new project and build the files from scratch.
1 Methods for complex data
Alexander Calder was an American artist well known for his hanging sculptures called mobiles. Look up some of his work - it is really neat.
We would like to help other artists who may want to design mobiles, so they can check ahead of the time whether their mobile will fit in the desired space (height, width, weight), and whether it will be properly balanced.
The following drawing shows two mobiles:
|
Simple mobile | |
| |
10 |
blue |
|
Complex mobile | |
| |
| |
------------+----- |
| | |
------+------ | |
| | | |
10 | 40 |
red 10 green |
blue |
We will restrict the mobile to two items hanging from each strut, and record for any item hanging at the end of the line its weight and its color.
We have decided on the following data representation for mobiles (the length refers to the length of the vertical string, the leftside amd rightside refer to the two parts of the strut):
+---------+ |
| IMobile |<---------------+ |
+---------+ | |
+---------+ | |
| | |
/ \ | |
--- | |
| | |
--------------------- | |
| | | |
+--------------+ +---------------+ | |
| Simple | | Complex | | |
+--------------+ +---------------+ | |
| int length | | int length | | |
| int weight | | int leftside | | |
| IColor color | | int rightside | | |
+--------------+ | IMobile left |----+ |
| IMobile right |----+ |
+---------------+ |
Convert this data definition into Java interfaces and classes and make several examples of mobiles. Include in your examples at least three mobiles, the first two as shown and the third one more complex that what is shown here:
Design the method totalWeight for the mobiles that computes the total weight of the mobile. We assume that the weight of the struts from which the mobile hangs is negligible, as is the weight of the string on which the disks hang.
Design the method totalHeight that computes the height of the mobile. Assume that the height of the disks is the same as their weight (i.e. a disk of weight 10 has height 10).
Design the method isBalanced that determines whether a mobile is balanced.
A simple mobile is always balanced.
A complex mobile is balanced if every mobile that hangs from it is balanced, and the weight of the left side multiplied by the length of the left strut equals the weight of the right side multiplied by the length of the right strut.
(So if I hang weight 3 on the left and weight 5 on the right, then the length on the left should be 5 and the lengh on the right should be 3 —
or both could be the same multiple of these numbers, e.g. 20 on the left and 12 on the right.)
The remaining two problems are harder. Do them, if you have the time, or finish them at home as a part of your protfolio problems. Think about them, but move on to the next problem.
Design the method buildMobile that combines this balanced mobile with the given balanced mobile and produces a new mobile as follows:
The method is also given the desired length of the string on which the new mobile will hang, and the strut that will be used to hang the two mobiles on. Your job is to make sure that the length of the strut is divided into the left and righ side in such way that the resulting mobile will also be balanced.
Design the method maxWidth that computes the maximum width of a mobile. The maximum width of a simple mobile is its weight divided by 10 (assume 10 is the lowest weight we will have - and use just integer arithmetic). For a complex mobile, assume you hang the mobile, and you want to make sure it will not hit the wall on the side regardless how it spins. The width then is the size of the room you will need. You may choose to compute the radius or the diameter, but must specify in the comment what was your choice.
2 Methods for collections of data
We would like to make a list of all addresses (given as just the name of a city and the state). The data definition for a list of addresses in DrRacket was
;; A [Listof Addresses] is one of |
;; -- empty |
;; -- (cons Address [Listof Addresses]) |
This corresponds to the following class diagram:
+---------------------+ |
| | |
v | |
+---------+ | |
| ILoAddr | | |
+---------+ | |
/ \ | |
--- | |
| | |
-------------------- | |
| | | |
+----------+ +---------------+ | |
| MtLoAddr | | ConsLoAddr | | |
+----------+ +---------------+ | |
+----------+ +-| Address first | | |
| | ILoAddr rest |-+ |
| +---------------+ |
v |
+--------------+ |
| Address | |
+--------------+ |
| String city | |
| String state | |
+--------------+ |
In Java, the class that represents the empty list must specify the type of list it will be - because it needs to refer to the common interface that represent both empty and nonempty lists of the given type.
We may compute the total cost of a list of books, count the number of vegetarian offerings in a list of menu items, and see if there are dangerous animals in a list of Zoo animals. These methods are specific for the type of data included in the list and depend on the type of data contained in the list.
DrRacket only realizes that we are asking whether a book is vegetarian when it encounters a wrong type of list (or just a wrong type of item within a list) at the time the program is running and the function is invoked. Static typing in Java detects this problem at the compilation time, but we pay the price by defining separate classes for representing empty lists for every type of list we deal with.
Note: Later in the course we will learn how to abstract over this code repetition.
Design the classes and interfaces that implement the data representation defined in this class diagram.
Make examples of data, including at least one list of addresses with at least four item in it.
Design the method countInState that consumes the name of a state and counts how many cities in a list are in the given state.
Design the method citiesInState that consumes the name of a state and produces a list of the addresses in the given state.
Design the method sortStates that sorts a list of addresses by the names of the state. Do not worry what happens if there are several cities in the same state.
Design the method sortCities that sorts a list of addresses by the names of the city. Do not worry what happens if there are several cities with the same name in more than one state.
For the last two problems you will need to use the following method defined in the class String:
// compare this String with the given String |
// produce int < 0 if the first one is before the second lexicographically |
// produce 0 if the two Strings are the same |
// produce int > 0 if the first one is after the second lexicographically |
int compareTo(String that); |