On this page:
2.1 Instructions
Practice Problems
Problem 1: Webpages
Problem 2: Avoiding repetition
Problem 3: Completing list-of-string methods for other representations
Problem 4: Nu Digs:   Tunneling beneath a university
Using the javalib library
8.3

Assignment 2: Designing methods for complex data

Goals: Learn to design methods for complex class hierarchies. Practice designing the representation of complex data.

2.1 Instructions

This homework should be done with your lab partner.

Be very, very careful with naming! Again, the solution files expect your submissions to be named a certain way, so that they can define their own Examples class with which to test your code. Therefore, whenever the assignment specifies:
  • the names of classes,

  • the names and types of the fields within classes,

  • the names, types and order of the arguments to the constructor,

  • the names, types and order of arguments to methods, or

  • filenames,

...be sure that your submission uses exactly those names. Additionally, make sure you follow the style guidelines that Bottlenose enforces. For now the most important ones are: using spaces instead of tabs, indenting by 2 characters, following the naming conventions (data type names start with a capital letter, names of fields and methods start with a lower case letter), and having spaces before curly braces.

You will submit this assignment by the deadlines using the course handin server. Follow A Complete Guide to the Handin Server for information on how to use the handin server. You may submit as many times as you wish. Be aware of the fact that close to the deadline the server may slow down to handle many submissions, so try to finish early. There will be a separate submission for each problem - it makes it easier to grade each problem, and to provide you with the feedback for each problem you work on.

Your submissions for this homework will be organized as follows:

Due Date: Tuesday, February 1st, 9:00 pm

Practice Problems

Work out these problems on your own. Save them in an electronic portfolio, so you can show them to your instructor, review them before the exam, use them as a reference when working on the homework assignments.

Problem 1: Webpages

The following DrRacket data definition describes a website as a collection of Webpages:

;; A Webpage is a (make-webpage String [List-of Content])
(define-struct webpage (name content))
 
;; A Content is one of
;; -- Text
;; -- Picture
;; -- Hyperlink
 
;; A Text is a (make-text String Number Boolean)
(define-struct text (name num-lines in-markdown?))
 
;; A Picture is a (make-picture String String Number)
(define-struct picture (name description megabytes))
 
;; A Hyperlink is a (make-link String Webpage)
(define-struct link (text destination))

We are giving you the names of the classes or interfaces you will probably need — make sure you use these names to define your interfaces and classes.

A reminder on naming conventions: For lists of data, the names of the interface should always start with ILo, while the two classes’ names start with MtLo for the empty lists and ConsLo for the nonempty lists; all three of these names should be followed by the name of the datatype of the elements of the list. So we would have ILoString, MtLoString, ConsLoString to represent lists of Strings, ILoBook, MtLoBook, ConsLoBook to represent lists of Books, etc.

Note: if it helps you at all in this assignment, you may assume that every name in this website is distinct.

Problem 2: Avoiding repetition

When your boss compared the output of totalCredits with the actual bill from the web hosting provider, they found that you overestimated how much the bill was. There were some repeated appearances of features in the methods you implemented. For this problem, copy your Webpages.java file to a new UniqueWebpages.java file, and fix that repetition. Note: the automated tests for the above problem expect that repetition, so you cannot submit the same file for both of these problems.

Hint: you should not need to create any new data definitions (i.e. interfaces) for this problem or revise existing ones (i.e. create new classes), though you may need to define some additional helper methods for existing ones.

Problem 3: Completing list-of-string methods for other representations

This is a much broader conception of the usefulness of interfaces, than simply as “tags” for indicating the options of union data. Most of our uses of interfaces this semester will be for union data, and we’ll explore this flexibility in more detail in OOD; for now, I want to give you a small “sneak preview” of that future mindset.

Your task in this problem is to think a bit differently about what it means “to be a list”: in Fundies 1, we said a list was always either '() or a cons. But in Fundies 2, a list is whatever can implement the ILoString interface. One way of looking at MtLoString and ConsLoString is that those two classes represent two ways of “putting lists together”. In class we briefly introduced two new implementations for the ILoString interface: SnocLoString that added one item to the end of a list, and AppendLoString that appended two lists together — these are evidently two other ways of “putting lists together”, and if they can successfully implement the methods needed, then they must be perfectly valid kinds of lists! We didn’t have time to sketch out implementations of methods on those classes in class, so in this problem, you’ll actually implement a few of those methods.

Hint: As a strong suggestion: build lots of examples of lists for this problem, and consider building multiple examples that represent the same elements in the same order, but that are constructed using different mixes of the classes above.

You do not need to implement other list methods (e.g. sort, size, etc.) for this problem, though you may choose to do so to aid your debugging or testing.

Problem 4: Nu Digs: Tunneling beneath a university

In this problem, you will be drawing and working with tree-shaped data representing a map of the tunnel system of a university like Northeastern’s. We will represent a map as implicitly starting from some entrance, and spreading out until it reaches the various exits of the tunnel system.

interface ITunnelSystem { /* see methods below */ }
 
// represents an exit from the tunnels class Exit implements ITunnelSystem {
}
 
// represents a straight section of tunnel class Hallway implements ITunnelSystem {
// How long this tunnel section is int length;
// The direction of this tunnel: one of the strings "N", "S", "E" or "W" String direction;
// The maximum number of students who can pass through this hallway per second int capacity;
// The rest of the tunnel system ITunnelSystem more;
}
 
// represents where one tunnel splits off from another class Fork implements ITunnelSystem {
// How long the two branches are int firstLength;
int secondLength;
// The number of students per second that can pass through the two hallways int firstCapacity;
int secondCapacity;
// The directions of both hallways: one of "N", "S", "E", or "W" String firstDirection;
String secondDirection;
// The remaining parts of the tunnel system ITunnelSystem first;
ITunnelSystem second;
}

Every tunnel in this system is aligned to one of the compass points; there are no diagonal tunnels here! Note: your code only needs to work for the specified four direction strings "N", "S", "E", or "W". You do not have to check or test for bogus directions, nor will we test your code on bogus directions.

Using the javalib library

The javalib library provides the support for the design of interactive games and creating images composed by combining geometric shapes as well as image files. See The Image Library for more information. You will need to use the pinhole-related methods for this project to correctly align smaller images into bigger ones. You may also want to deliberately draw things in addition to the required pictures: just like an artist might sketch out guidelines or reference points, you might want to add debugging aids to your image. You will likely find that FrameImages are useful for figuring out just how big the boundaries of your images are, and VisiblePinholeImages are useful for seeing just where the pinhole of an image is; there may be other ways to debug your drawing, as well.

To use the library, download the javalib file above and add it to your project the same way you have added the tester library.

At the top of the .java file where the library is used, add the following import statements:

import tester.*; // The tester library import javalib.worldimages.*; // images, like RectangleImage or OverlayImages import javalib.funworld.*; // the abstract World class and the big-bang library import java.awt.Color; // general colors (as triples of red,green,blue values) // and predefined colors (Color.RED, Color.GRAY, etc.)

You can test images using check-expect just as you can check other values:
boolean testImages(Tester t) {
return t.checkExpect(new RectangleImage(30, 20, OutlineMode.SOLID, Color.GRAY),
new RectangleImage(30, 20, OutlineMode.SOLID, Color.GRAY));
}

But note that you must construct the images in the same manner: for example, the following test will fail:
boolean testFailure(Tester t) {
return t.checkExpect(
new ScaleImageXY(new RectangleImage(60, 40, OutlineMode.SOLID, Color.GRAY), 0.5, 0.25),
new RectangleImage(30, 15, OutlineMode.SOLID, Color.GRAY));
}

Finally, you can display your images so that you can see whether you’re on the right track, as follows:

boolean testDrawTree(Tester t) {
WorldCanvas c = new WorldCanvas(500, 500);
WorldScene s = new WorldScene(500, 500);
return c.drawScene(s.placeImageXY(myTree.draw(), 250, 250))
&& c.show();
}

See The Image Library for more information.