8.3

#### Assignment 3: Abstracting over Data Definitions; Custom constructors; Accumulators

Goals: Learn to use the String class, practice working with lists. Learn to design methods for complex class hierarchies.

##### Instructions

This assignment is long. Start early.

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.

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 deadline using the Bottlenose submission system. You may submit as many times as you wish. Be aware of the fact that close to the deadline the system may have a long queue of submissions which means it takes longer for your code to be submitted - so try to finish early.

The submission will be organized as follows:

• Homework 3 Problem 1: The Media.java file

• Homework 3 Problem 2: The Bagel.java file

• Homework 3 Problem 3: The Trigrams.java file

Due dates:
• Tuesday, February 8th at 9:00pm

### Problem 1:Abstracting over Data Definitions

Related files:
Media.java

In this problem, our data will represent different kinds of media. Each piece of media has a title and list of available languages for captions. Different kinds of media can also contain additional information as shown in the supplied Media.java file.

Note: none of these methods are properly implemented. As given in the file, they are all stubs that currently return a dummy value, so the code will compile but not yet work.

• Make at least two examples of data for each of the three classes.

• Design the isReallyOld method for each class. TV and YouTube are fairly modern formats, but movies that came out before 1930 are considered really old.

• Design the method isCaptionAvailable for each class, which determines if a given language is available for captions.

• Design the method format which produces a String showing the proper way to display the piece of media in text. Movies are formatted by the title followed by the year in parentheses, such as "The Favourite (2018)". TV episodes are formatted by the show’s title followed by the season and episode number, separated by a period, followed by a dash and then the episode title, such as "Mad Men 1.1 - Smoke Gets In Your Eyes". YouTube videos are formatted by the video’s title followed by the word by followed by the channel name, such as "Threw It On The Ground by thelonelyisland".

Once you have finished these methods and are confident that they work properly, save the work you have done to a separate file. Do not submit the code as written so far. The problems below are the main point of this exercise, and it will be helpful for you to preserve the code written so far as a reference against which to compare your revised code below. Again, submit only the work below.

• Look at the code and identify all places where the code repeats — the opportunity for abstraction.

Lift the common fields to an abstract class AMedia, which should implement IMedia.

Make sure you include a constructor in the abstract class, and change the constructors in the derived classes accordingly. Run the program and make sure all test cases work as before.

• For each method that is defined in all three classes decide to which category it belongs:

• The method bodies in the different classes are all different, and so the method has to be declared as abstract in the abstract class.

• The method bodies are the same in all classes and it can be implemented concretely in the abstract class.

• The method bodies are the same for two of the classes, but are different in one class — therefore we can define the common body in the abstract class and override it in only one derived class.

Now, lift the methods that can be lifted and run all tests again.

Submit your work in a file named Media.java.

### Problem 2:Working with Custom Constructors, A Taste of Equality

A BagelRecipe can be represented as the amount of flour, water, yeast, salt, and malt in the recipe. A perfect bagel results when the ratios of the weights are right:

• the weight of the flour should be equal to the weight of the water

• the weight of the yeast should be equal the weight of the malt

• the weight of the salt + yeast should be 1/20th the weight of the flour

Design the BagelRecipe class. The fields should be of type double and represent the weight of the ingredients as ounces. Provide three constructors for this class:

• Your main constructor should take in all of the fields and enforce all above constraints to ensure a perfect bagel recipe.

• Provide another constructor that only requires the weights of flour and yeast, and produces a perfect bagel recipe.

• Provide another constructor that takes in the flour, yeast and salt as volumes rather than weights, and tries to produce a perfect recipe. Here, too, a perfect recipe should be enforced.

Flour and water volumes are measured in cups, while yeast, salt, and malt volumes are measured in teaspoons.

• 48 teaspoons = 1 cup

• 1 cup of yeast = 5 ounces

• 1 cup of salt = 10 ounces

• 1 cup of malt = 11 ounces

• 1 cup of water = 8 ounces

• 1 cup of flour = 4 and 1⁄4 ounces

You should use an IllegalArgumentException with a helpful message if the above constraints cannot be enforced.

Once you’ve completed the above constructors, you should:
• Remove as much duplicate code as possible from these constructors.

• Implement the method sameRecipe(BagelRecipe other) which returns true if the same ingredients have the same weights to within 0.001 ounces.

Submit your work in a file named Bagel.java.

### Problem 3:Trigrams

Technically, this is a word-level trigram. There are also letter-level trigrams, which are simply three-letter sequences. The generalized version of these are called $$n$$-grams.

A trigram is a three-word phrase, such as “three word phrase”. Trigrams are often used in machine-learning and search applications, to find documents matching a given search phrase, or to summarize a document by its most common terms.

• For this problem, simply represent a document as a list of Strings. Each string will be a single word of the document, and no word will contain a space in it.

• Design a class Trigram to represent trigrams. I strongly recommend that you not represent a trigram by a single String...

• Design a method compareTo(Trigram other) for Trigram that behaves analogously to compareTo for Strings: it should return a negative number if this Trigram comes before the other Trigram, a positive number if this Trigram comes after the other Trigram, and zero if they are the same trigram. This method should order the trigrams lexicographically and case-insensitively.

• Note the font here: I’m showing a document and trigrams in quotes, but they are not meant to signify Java Strings; you can and should represent these using whatever classes you’ve designed.

Design a method on lists of strings, trigrams(), that converts the list into a list of trigrams. For example, the document “Fundies2 is lots of fun” should produce the three trigrams “Fundies2 is lots”, “is lots of”, “lots of fun”. (A document with fewer than three words will produce an empty list of trigrams.)

• Design a method mostCommonTrigram() for lists of trigrams that returns the most common Trigram in the list. If the list is empty, return the trigram “NO SUCH TRIGRAM”. For ties, return the first trigram (in compareTo ordering) you encounter with the highest frequency.

• Design a method count(Trigram trigram) for lists of trigrams that returns the count of a given trigram in this list.

You will likely need several helper methods for this assignment. Be sure to test your code thoroughly. Hint: you will need to use one or more accumulators on this problem. Be sure to clearly explain their meaning in an accumulator statement, which should be written just beneath the purpose statement, just as we did in Fundies 1.

Submit your work in a file named Trigrams.java.