CS361 Spring 2008

Final Takehome Exam
Handed out: Friday, May 9
Due: 11 am, Friday, May 16

Do all 7 problems. You have 7 days to do this exam. There are 100 possible points.

Notes

Problems

  1. (14 pts) As you may recall from CS231, a graph is a finite set of nodes, some of which are connected by one or more edges. (If you are totally unfamiliar with graphs, please see me and I'll give you some examples--you can also look in your data structures book for more info.) For example, here is an implementation of a general-purpose Graph class and associated GraphNode and Edge classes. The Graph class stores the nodes and edges in sets. Each node keeps track of the edges connected to it. Each edge keeps track of the nodes on its two ends.
    1. Modify the design and implementation of the Graph, Edge, and GraphNode classes to make them more elegant, if possible. (But do not replace them with a completely different set of classes.) Justify your modifications.
    2. A graph is bipartite (or two-colorable) if the set of nodes can be partitioned into two sets so that each edge goes from a node in one set to a node in the other set. Equivalently, a graph is bipartite if the nodes can be colored using only two colors so that the nodes on the ends of each edge are opposite colors. The easiest way to determine whether a graph is bipartite is to traverse the graph, coloring the nodes alternate colors as you go. If you encounter an already-colored node that is the wrong color, the graph is not bipartite. Otherwise, it is bipartite. As you are traversing the graph, there are at least 3 ways to keep track of the colors of the nodes:
      1. add a Color field to the GraphNode class
      2. add a Map<GraphNode,Color> field to the Graph class that, for each node, stores its color.
      3. add two fields to the Graph class of type Set<GraphNode>. One field stores the blue nodes and the other stores the red nodes.
      Which of these three approaches is best, if any? If there is a fourth way that is better than any of these, give it. Briefly explain.

  2. (8 pts) Do exercise 18 from Chapter 8 of my textbook, except using the drawer6 package instead of the drawer5 package. That is, add a new "Filled Rect" button to the drawer6 package that, when clicked, allows filled rectangles to be drawn on the canvas. Do it in an elegant way. Report exactly how many
    1. new files needed to be created,
    2. existing files needed to be modified and
    3. places existing files needed to be modified.
  3. (16 pts) Do exercise 30(a) from Chapter 8 of my textbook. That is, enhance the drawer6 package by adding "Cut", "Copy", "Paste", and "Delete" menu items to the Edit menu. When you paste some figures, the newly-pasted figures should be the only selected ones. You do not need to use the system clipboard, but you can get extra credit if you do. Of course, your implementation should be elegantly done.
  4. (8 pts) Consider the following UML diagram for part of an online business. The shopping cart will contain zero or more purchases. Each purchase consists of the item to be purchased and a shipping option for that item.

    Suppose the Cart's cost() method is implemented as follows:
        public int cost() {
            int total = 0;
            for(int i = 0; i < purchases.size(); i++) {
                Purchase p = (Purchase) purchases.get(i);
                total += p.item().cost() + p.shipping().cost();
            }
            return total;
        }
    Also, suppose the Cart’s maxDays() method is implemented as follows:
        public int maxDays() {
            int max = 0;
            for(int i = 0; i < purchases.size(); i++) {
                Purchase p = (Purchase) purchases.get(i);
                max = Math.max(max, p.shipping().days());
            }
            return max;
        }
    Refactor this design to make it more elegant. You are welcome to add/remove classes and methods if it is helpful. Briefly explain why your design is more elegant.
  5. (10 pts) Discuss the elegance of the following code. If it is not elegant, explain why and suggest improvements.
    import java.util.ArrayList;
    
    public class BookLibrary {
        private ArrayList myBooks = new ArrayList();
    
        public void rename(String oldName, String newName) {
            //loop thru array to find the book to be renamed
            Book aBook = null;
            for( int i = 0; i < myBooks.size(); i++ ) {
                    Book tempBook = (Book) myBooks.get(i);
                if( tempBook.getName().equals(oldName)) {
                        aBook = tempBook;
                        break;
                }
            }
            //rename the book if match was found in array
            if(aBook == null) return;
            aBook.setName(newName);
        }
    
        ...other methods and instance variables...
    }
    
    class Book
    {
        private String name;
    
        public String getName() { return name; }
        public void setName(String newName) { name = newName; }
    
        ...other methods and instance variables...
    }
  6. (10 pts) Suppose you have an application to maintain and to expand and the code is a real mess (poor architecture, runs slowly, has huge methods, brittle and unreadable code, poor or non-existent documentation, etc.). There are two approaches that you can take to fix things up:
    1. Refactor the code to try to get rid of the bad features.
    2. Start over from scratch, incorporating all the lessons learned from the previous version.
    Which approach is better? Discuss the advantages and disadvantages each approach.
  7. (34 pts) Design a scoring program for Woodsmen's competitions. These competitions traditionally include events such as axe throwing, fire building, chain saw cutting, pole climbing, tree felling, chopping, splitting, rolling, throwing. Here are the specifications for the program:
    1. An arbitrary number of schools can compete.
    2. There can be an arbitrary number of teams from each school.
    3. A team consists of 6 people.
    4. There are women's teams, men's teams, and mixed teams.
    5. For each event, there are one or more judges, a scorekeeper, and timers.
    6. All events in the competition are either individual (one-person) events, two-person events, three-person events, or team (six-person) events.
    7. Each competition can vary in terms of which events are included. For example, one competition may include tobacco spitting as one of the individual events whereas another competition may have axe juggling instead.
    8. Each competitor competes in one individual event, one pair event, one three-person event, and one team event.
    9. Each event is scored differently, including different kinds of penalties. Also, for some events the winner is the one with the lowest score (e.g., the quickest team building a fire) and in other events the winner is the one with the highest score (e.g., the team that spits tobacco the farthest). All scores are ultimately converted to a number between 0 and 100 (100 being best).
    10. The program needs to determine overall rankings of male teams and female teams separately, based on the total score on all events in which the team participated. The mixed-gender teams are grouped with the male teams. Awards are presented to the top male team and top female team.
    11. The program also needs to determine rankings of all teams in each event since there will be an award for the winner of each event.

    In an actual competition, the user of the program would start up the program and then enter all the information about the events, teams, and players through some GUI. Then, as the competition progressed, the user would use the GUI to enter the data gathered for each event (e.g., the time or distance for each team, any penalties, etc.). When the competition ended, the final scores would be computed from the data and then the scores and rankings of all teams in all events would be displayed.

    Design the underlying model and ignore the GUI. Create UML diagrams, including methods and fields, as appropriate. You don't need to implement anything, but implementing parts of it may help you see faults in your design.

    The easier it is for me to understand your design, the more points you'll get, so you might want to include some explanations as to why you made particular decisions regarding various parts of the overall design.

    Treat me as the customer who is paying you to develop the software and so ask me for any clarifications you need in order to finish your design. As usual, I will share the clarifications with everyone, if appropriate.