INST2002 Programming 2:
Support Sheet for Online Assessment 2
Set by: Luke Dickens
Available from 27th November, 2015
Due at 2pm on 8th December, 2015
Important Notice
This assessment forms part of your degree assessment. It must be done entirely
on your own from start to finish:
• You must not collaborate or work with other students at any stage.
• You must not send or show other students your answers.
• You must not ask other students for help, or ask to see their answers. As well as being
against regulations, this is unfair to the other student concerned, since it may lead to
them being accused of plagiarism.
• You must not seek help from friends, relatives, online discussion groups other than the
moodle forum for INST2002
• If you think any of the description of the task below is ambiguous or unclear, please
post to the moodle forum, explaining what your concerns are, or raise it in person with
your lecturer, Luke Dickens, or a INST2002 lab demonstrator.
• If you are unsure of any of the above points, please post your concern to the moodle
forum.
Finally, if there is any reason you do not think you can complete this assessment in
the alloted time, you should either make a formal request for an extension with your
home department, or discuss your reasons with the INST2002 lecturer, Luke Dickens at
l.dickens@ucl.ac.uk.
1 A Chat Room with a Profanity Filter
Imagine that you are asked to write code to support a collection of simple text based online
chat-rooms, with a configurable profanity filter. The chat-rooms consist of users posting
short text messages (posts), which are visible to others in the chat-room alongside the name
of the user who posted it. When reading these posts, some users will want profanities to be
filtered out, while some will not. For simplicity, we will assume that the list of profanities
1
are the same for all users and in all chat-rooms. However, it should be possible to add and
remove words from the profanity filter.
For example consider the following sequence of messages in a chat room whose name is
VictorianGents.
post order username text
0 “Raffles” “Hello Bunny, are you there?”
1 “Bunny” “Here I am, Raffles.”
2 “Raffles” “Excellent Bunny. Have you seen Dave
the nincompoop?”
3 “Dave” “How dare you call me a nincompoop, you
rapscallion.”
4 “Raffles” “Oh tish and pish Dave. Quit your
blithering, you twit.”
5 “Dave” “Zounds! You knave! I’ll not suffer
your insults further.”
6 “Raffles” “Gadzooks! Was it something I said
Bunny?”
Table 1: An example chat history for the VictorianGents chat-room.
Now, imagine that a technician has added the following terms to the profanity filter:
“blither”, “blithering”, “gadzooks”, “knave”, “pish”, “nincompoop”, “rapscallion”,
“tish”, “twit”, and “twits”.
Without the profanity filter switched on, the chat history for the VictorianGents chat
room would display to screen as shown in Figure 1:
Chat Room VictorianGents :
Raffles : Hello Bunny , are you there ?
Bunny : Here I am , Raffles .
Raffles : Excellent Bunny . Have you seen Dave the nincompoop ?
Dave : How dare you call me a nincompoop , you rapscallion .
Raffles : Oh tish and pish Dave . Quit your blithering , you twit .
Dave : Zounds ! You knave ! I ’ ll not suffer your insults further .
Raffles : Gadzooks ! Was it something I said Bunny ?
Figure 1: Unfiltered chat history for VictorianGents displayed to screen
If the same chat history were again displayed to screen, this time with the profanity filter
switched on, then it would appear as in Figure 2.
Note: All parts of the original text that match a word stored in the profanity filter has
had each character replaced with an asterisk, *, in the filtered text.
Note: The word “blithering” in Figure 1 has been replaced in Figure 2, with “**********”.
This is the case even though the shorter word “blither” is also in the list.
2
Chat Room VictorianGents [ filtered ]:
Raffles : Hello Bunny , are you there ?
Bunny : Here I am , Raffles .
Raffles : Excellent Bunny . Have you seen Dave the **********?
Dave : How dare you call me a ********** , you ***********.
Raffles : Oh **** and **** Dave . Quit your ********** , you ****.
Dave : ******! You *****! I ’ ll not suffer your insults further .
Raffles : ********! Was it something I said Bunny ?
Figure 2: Filtered chat history for VictorianGents displayed to screen
Note: If there is a choice between filtering one of two words, e.g. either “blither” or
“blithering”, then the longer profanity should be replaced with asterisks. If two equally
long profanity words overlap, then either word may be replaced with asterisks.
Note: The profanity filter should be case-insensitive, meaning that it should filter words
whether they appear in uppercase, lowercase or a mixture of cases, e.g. if “blithering” is
a profanity word, then it should filter “blithering”, “BLITHERING”, “Blithering”, and so
on.
Note: For simplicity, the profanity filter should filter any sequence of characters matching
a profanity, even if that word is contained within another word, e.g. if “tish” is a
profanity word then the text, “I am British”, should be filtered to be “I am Bri****”.
In a real world profanity filter, this may not be the preferred behaviour.
Finally, it should be possible to look at the history of just one user, with or without the
filter applied. For instance, if we wanted to see just Raffles history filtered and printed to
screen then it would appear as in Figure 3.
Chat Room VictorianGents [ filtered ]:
Raffles : Hello Bunny , are you there ?
Raffles : Excellent Bunny . Have you seen Dave the **********?
Raffles : Oh **** and **** Dave . Quit your ********** , you ****.
Raffles : ********! Was it something I said Bunny ?
Figure 3: Filtered chat history for VictorianGents displayed to screen
2 Your Task
In the code file Problem.java given to you, there are four classes: a public class Problem,
and three package visible classes Post, ProfanityFilter, and ChatRoom. The class Problem
has been written for you to test the code, and you do not need to edit this class. However,
you may choose to edit this class to test your changes as you go. The class Post has also
been written for you. Post is a very simple class that stores the user-name and text of a
chat-room post, and can convert these two pieces of information to a String. You must
3
not edit the class Post. You will need to edit the other two classes, ProfanityFilter
and ChatRoom. The required changes are described below.
2.1 The ProfanityFilter class
A ProfanityFilter object contains a collection of Strings each of which is a profanity, i.e.
a word that should be filtered out. It also provides methods for filtering out these profanities
in text. You should implement the following in ProfanityFilter.
• One or more fields to the ProfanityFilter class to store the Strings representing the
profanity words.
• A constructor, which takes no arguments and constructs an empty ProfanityFilter,
i.e. a ProfanityFilter with 0 profanity words contained in it.
• An addProfanity method, which takes a String as input, and includes it as a profanity
word.
• A removeProfanity method, which takes a String as input, and removes it from the
collection of a profanity words if it is present. Otherwise, it should do nothing.
• A getProfanities method, which takes no arguments and returns a String array of
all the profanities stored in the ProfanityFilter.
• A sortProfanitiesByLength method, which takes no arguments and sorts the profanities
by length, with the longest words appearing first and the shortest appearing
last. Two profanity words of the same length can appear in either order. After a
call to sortProfanitiesByLength, the getProfanities method should return the
profanities in length order.
• A static method filterWordInText, which takes two Strings as arguments: profanity
– a word which should be replaced with a dummy string of asterisks; and text – the
text in which profanity will be replaced. The method should return a string of filtered
text, i.e. text with every occurance of profanity replaced by a String of asterisks
of the same length.
For example, if text is the String “Quit your blithering, you twit.” and profanity
is the String “blithering”, then filterWordInText should return “Quit your
**********, you twit.”. You may find it helpful to use the method createDummyString
for filterWordInText.
Note: This method can be implemented with loops, or recursion. You will get extra
credit if you use recursion. However, you must not use the String methods indexOf,
or replace (or any other method containing the words indexOf or replace).
• A method filterText, which takes a String called text as argument and returns a
String which is a copy of the input text with all stored profanity words replaced by
asterisks.
Note: You should filter for the longest profanity words first.
4
2.2 The ChatRoom class
A ChatRoom object contains a collection of Posts in the order in which they were posted.
ChatRoom objects provide methods to get histories of filtered and unfiltered posts.
All ChatRoom objects have access to the same ProfanityFilter object, which they
can use to filter out bad-language. This ProfanityFilter can be accessed by the static
getProfanityFilter method, and set by the static setProfanityFilter method. Both
these methods are provided for you. Each ChatRoom also has two instance fields: the
roomName of type String, which is the name of the chat-room; and posts of type ArrayList<Post>,
which collects all messages posted to the chat-room. There are some other methods provided
for you too, see the code for details.
You will need to implement the following methods in ChatRoom:
• A constructor, which takes a single argument roomName of type String and stores this
as the chat-room name. This constructor should create a ChatRoom with 0 posts in its
history.
• A getRoomName method, which is a simple getter method for the roomName field.
• An addPost method, which takes two Strings as input: author – the author of the
post; and text – the text of the post. This method should store this information as a
Post.
• A getHistory method, which takes no arguments and returns a String array, containing
the unfiltered string representations of each post to the chat-room, in the order
they were added (by addPost).
• A getFilteredHistory method, which takes no arguments and returns a String
array, containing the filtered string representations of each post to the chat-room, in
the order they were added.
Note: Filtered posts are those that have been filtered by the ProfanityFilter. These
should filter both the author name and text of the post.
• A getAuthorHistory method, which takes a String argument author, and returns
a String array, containing the unfiltered string representations of each post to the
chat-room by author. Again, posts should be displayed in the order they were added.
• A getFilteredAuthorHistory method, which takes a String argument author, and
returns a String array, containing the filtered string representations of each post to
the chat-room by author. Again, posts should be displayed in the order they were
added.
Note: Filtered posts are those that have been filtered by the ProfanityFilter. These
should filter both the author name and text of the post.
3 Some Rules and Advice
You have been provided with signatures for all the methods described above in the code.
You should not change any of these signatures. In particular, for the methods provided in
the code:
5
• Do not change the return type.
• Do not change the visibility, e.g. public.
• Do not change the number or type of the input arguments.
• Do not change whether a method is static or not.
You may write your own additional methods, and you may add fields to the ProfanityFilter
and ChatRoom classes. In some cases, it may be easier to solve the problem if you define
helper methods, and you will be given credit if these are used appropriately.
You may find some of the standard Java library helpful to solve this problem. For
instance, the String class and its methods: length, toLowerCase, substring (2 overloaded
methods). getChar, and equals. You may also find the following methods in ArrayList
helpful: size, toArray, get, set, and remove. Make sure that you read up on how to use
these methods in the Java documentation. However, you must not use the String methods
indexOf, or replace (or any other method containing the words indexOf or replace), and
anyone using these methods will not get full marks for the associated task.
Finally, it is sometimes better to use an array and sometimes it is better to use an
ArrayList. You must decide when one is better than the other. You can always convert
from one to the other when needed.
4 A Local Copy of the Code
If you go to moodle, you can access a local copy of the code. This is the same code that will
appear in the text box when you finally log in to TestDome. You can experiment with this
local copy to test your ideas, before you log in to TestDome. Try compiling this local code
to start with, then running it to see what happens. At this point, try to make changes in
line with the description above, and recompile and run regularly to test your changes.
There is more than one way to solve this problem, and so long as you follow the instructions
and pass all the tests on TestDome you will be given a minimum of 80% overall1
.
Additional marks will be given for coding style and comments, up to a maximum of 20%.
This includes, but is not limited to: good names for variables, appropriate use of control
flow (e.g. for loops and if statements), meaningful and appropriate comments, minimising
duplication of code, appropriate helper methods, and consistent formatting of code.
1Note that if you use the forbidden methods indexOf, or replace (or any other method containing the
words indexOf or replace) then you will not get full marks for the associated task.
6
INST2002 Programming 2:
Leave a Reply
INST2002 Programming 2:
INST2002 Programming 2:
This assessment forms part of your degree assessment. It must be done entirely
on your own from start to nish:
You must not collaborate or work with other students at any stage.
You must not send or show other students your answers.
You must not ask other students for help, or ask to see their answers. As well as being
against regulations, this is unfair to the other student concerned, since it may lead to
them being accused of plagiarism.
You must not seek help from friends, relatives, or online discussion groups other than
the moodle forum for INST2002
If you think any of the description of the task below is ambiguous or unclear, please
post to the moodle forum, explaining what your concerns are, or raise it in person with
your lecturer, Luke Dickens, or a INST2002 lab demonstrator.
If you are unsure of any of the above points, please post your concern to the moodle
forum.
Finally, if there is any reason you do not think you can complete this assessment in
the alloted time, you should either make a formal request for an extension with your
home department, or discuss your reasons with the INST2002 lecturer, Luke Dickens at
l.dickens@ucl.ac.uk.
1 A Fast-Food Restaurant Menu System
Imagine that you are asked to write code to support an automated system for taking fast-
food restaurant orders, and to implement this for a particular fast-food restaurant of your
chosing. The main class RestaurantProg runs a simple interactive interface for a user: to
see menu items available to them at your fast food restaurant; to select one or more menu
items and add them to their order; and to see a running total price of their order, which
1
accounts for any discounts. Initially, RestaurantProg will only print a menu to screen. Until
you complete Section 2, you do not need to edit RestaurantProg. When you get to Section
3, you should uncomment the remaining code in RestaurantProg.
You have also been given a class Prices which gives you a simple way of converting int
prices into Strings. You do not need to edit this class.
You should begin by completing the implementation of Menu, MenuItem and the sub-
classes of MenuItem, the requirements are described in more detail in Section 2. After
which, you should attempt to implement Order, OrderEntry and the implementing classes
of OrderEntry, the requirements are described in more detail in Section 3.
2 Creating the Menu
A menu can contain dierent kinds of menu items, including main dishes, supplementary
dishes and drinks. To capture this, you should complete the implementation of the Menu and
MenuItem classes, as well as writing two additional classes MainDish and SupplementaryDish
(each extends the MenuItem abstract class). The class Drink has already been implemented
for you, and also extends the MenuItem abstract class.
You will need to write MainDish and SupplementaryDish from scratch. You can use
Drink as an example of how to do so. However, you need to decide whether MainDish
and SupplementaryDish are direct subclasses or whether you should structure the class
hierarchy dierently. Once you have implemented the classes in the section, you should be
able to compile and run the code, and it will create an example menu then print it to the
screen.
Look at the UML class diagram in Figure 1. This should the classes relevant to this
part of the coursework. The green classes have already been implemented for you, but the
yellow classes will require some implementation from you. In particular, you will need to
implement MainDish and SupplementaryDish from scratch.
The MenuItem class
You do not have to make any changes to this class. MenuItem is an abstract class that
represents items that can appear on the menu. Key methods in this class are:
A constructor that takes 3 arguments: id, name and unitPrice. Here id is the two
character String used to uniquely identify each MenuItem, name is a String holding
a short name of the item, and unitPrice is an int holding the price for a single unit
of the item.
getPrice { an abstract method. This takes a single int input units and has int
return type. Concrete subclasses of MenuItem should implement getPrice so that it
returns the price, in pence, of a given number of units of the item. This should take
account of any multi-unit discounts available for this MenuItem (see below for more
details).
toMenuLine { an abstract method. Concrete subclasses of MenuItem should imple-
ment toMenuLine so that it returns a line of text showing the product id, name and
various other details for the item (see below for more details).
2
Menu
-items: List<MenuItem>
+addMenuItem(item: MenuItem) : void
+isExistingItem(testId: String): boolean
+getItem(requestedId: String): MenuItem
+createExampleMenu(): Menu
MenuItem
-id: String
-name: String
-unitPrice: int
+getId() : String
+getName() : String
+getPaddedName() : String
+idMatches(testId: String) : boolean
+getPrice(units: int): int
+toMenuLine(): String
? ? ? ?
SupplementaryDish
???
+getPrice(units: int) : int
+toMenuLine(): String
MainDish
???
+getPrice(units: int) : int
+toMenuLine(): String
Drink
volume: int
+getPrice(units: int) : int
+toMenuLine(): String
Figure 1: A UML class diagram of the Menu class and its related classes and interfaces.
3
idMatches { a method that takes a single String argument, testId, and returns true
if this matches the id of the MenuItem, and false otherwise.
The above methods are already implemented. Additionally, the standard getter meth-
ods, and the method getPaddedName have also been implemented for you. getPaddedName
produces a xed length string (24 characters) containing the MenuItem’s name, and is to
help you write the toMenuLine method. There is no need to edit this class.
The MainDish class
You will need to create this class and write all the specied methods. You may add any
elds or additional methods you require. MainDish is a concrete subclass of MenuItem that
represents main-dishes at the restaurant. As well as having an id, name and unit-price,
a MainDish also records whether the dish is vegetarian or not. You must implement the
constructor, an isVegi method, and the two abstract methods of MenuItem: getPrice and
toMenuLine. The details of the required implementation are as follows:
A constructor that takes 4 arguments: id, name, unitPrice and vegetarian. Here
id, name, and unitPrice have the same meaning as in MenuItem. vegetarian is true
if the dish is vegetarian, and false otherwise.
isVegi { a simple getter method, this returns true if the dish is vegetarian, and false
otherwise.
getPrice { This overrides the corresponding abstract method in MenuItem. It takes
a single int input, units, and returns the price, in pence, of the given number of
units of the main dish. Main-dishes have multi-unit discounts: all main dishes can be
produced in single, double or triple portions respectively costing 1, 1:5 and 2 times the
unitPrice. If more than one dish is requested, the customer is given as many triple
portions as possible, and the remainder made up with a double or single portion. For
instance, if 8 portions are requested, the customer will be charged for 2 triple portions,
and 1 double portion.
toMenuLine { This overrides the corresponding abstract method in MenuItem. It
takes no input arguments, and returns a line of text showing (in the following order):
the product id, the name, a v if it is vegetarian and the price for a single, double and
triple dish. For instance, the code:
MainDish main1 = MainDish (“01″, ” Chicken Tikka “, 450 , false );
MainDish main2 = MainDish (“07″, ” Mixed Vegetable Curry “, 400 , false );
System . out. println ( main1 . toMenuLine ());
System . out. println ( main2 . toMenuLine ());
should produce output similar to:
01: Chicken Tikka 1 at 4.50 , 2 at 6.75 , 3 at 9.00
07: Mixed Vegetable Curry v 1 at 4.00 , 2 at 6.00 , 3 at 8.00
4
The SupplementaryDish class
You will need to create this class and write all the specied methods. You may add any elds
or additional methods you require. SupplementaryDish is a concrete subclass of MenuItem
that represents supplementary-dishes at the restaurant, such as rice and bread dishes. This
is very similar to the MainDish class, having an id, name and unit-price, as well as recording
whether the dish is vegetarian or not. As before, youmust provide a constructor, an isVegi
method, and implementations of the two abstract methods: getPrice and toMenuLine. The
details of the required implementation are as follows:
A constructor that takes 4 arguments: id, name, unitPrice and vegetarian. All
inputs have the same meaning as in MainDish.
isVegi { This has the same meaning as in MainDish.
getPrice { This overrides the corresponding abstract method in MenuItem. It takes a
single int input, units, and returns the price, in pence, of the given number of units
of the supplementary dish. Supplementary-dishes have multi-unit discounts: the rst
unit ordered is charged at the unitPrice, subsequent units are charged at 80% of the
unitPrice. For example, if the unitPrice is 1:00, then 1 unit is 1:00, 2 units are 1:80,
3 units are 2:60 and so on.
toMenuLine { This overrides the corresponding abstract method in MenuItem. It
takes no input arguments, and returns a line of text showing (in the following order):
the product id, the name, a v if it is vegetarian, the price for the rst unit then the
price for subsequent units. For instance, the code:
SupplementaryDish supp1 = SupplementaryDish (
“12”, ” Plain Naan “, 80, false );
SupplementaryDish supp2 = SupplementaryDish (
“13”, ” Keema Naan “, 200 , false );
System . out. println ( supp1 . toMenuLine ());
System . out. println ( supp2 . toMenuLine ());
should produce output similar to:
12: Plain Naan v 0.80 for 1, then 0.64 each
13: Keema Naan 2.00 for 1, then 1.60 each
The Drink class
You do not have to make any changes to this class. Drink is a concrete subclass of MenuItem
that represents drinks at the restaurant. As well as inheriting an id, name and unit-price, a
Drink also records its volume as an int. Some details of the key methods are as follows:
A constructor that takes 4 arguments: id, name, unitPrice and volume. Here id,
name, and unitPrice have the same meaning as in MenuItem. volume is the volume
of the drink in millilitres.
5
getVolume { a simple getter method, this returns the volume of the drink.
getPrice { This overrides the corresponding abstract method in MenuItem. It takes a
single int input, units, and returns the price, in pence, of the given number of units
of the drink. There are no multi-unit discounts available for drinks, instead each unit
is charged at the unit-price.
toMenuLine { This overrides the corresponding abstract method in MenuItem. It
takes no input arguments, and returns a line of text showing (in the following order):
the product id, the name, the volume and the unit price.
This information is provided for information only. You do not need to edit this class.
Look at the code or Figure 1 for more details.
The Menu class
You will need to edit this class. You may add any elds or additional methods you require.
Menu is a simple class for holding a collection of MenuItems, displaying them to screen,
and selecting them based on their ids. Key methods that you will need to implement in this
class are:
isExistingItem: returns true if a MenuItem in items has the same id as the input
testId.
getItem { this gets an existing MenuItem whose id matches the input requestedId.
If no such MenuItem appears in items then this method should throw an Exception.
addMenuItem { this takes a MenuItem as input, and if there is no MenuItem already
stored in items with the same id, it should add this to the items eld . The method
should throw an Exception when the id of the new MenuItem matches the id of an
existing MenuItem.
createExampleMenu { this is a static method that creates a new Menu object, and pop-
ulates it with MainDish, SupplementaryDish and Drink objects. You should choose
a name for your restaurant, and add at least 4 main dishes, 3 supplementary dishes
and 2 drinks, remember to include vegetarian and non-vegitarian dishes. There are
some examples of main-dishes, supplementary-dishes and drinks being created already
in this method, please replace these with your own menu-items.
You will need to edit all the methods in the above list. A constructor and the
toString method has been implemented for you.
3 A customer’s order
Do not attempt this part until you have implemented the classes required by Section 2.
You should now implement the classes that will allow customers to order items from the
menu, and to keep track of these orders. Begin by looking at Figure 2. The classes in yellow
will require some implementation from you. Those in green have been provided for you, and
do not need any changes. To test your changes in this section you should uncomment the
remaining code in RestaurantProg.
6
Order
-entries: List<OrderEntry>
+Order()
+orderMenuItem(
newItem: MenuItem, quantity: int) : void
+addDiscountVoucher(
voucherCode: String, voucher: Voucher) : boolean
+calculateTotal() : int
+toOrderLine() : String
<<interface>>
OrderEntry
+orderEntryPrice(): int
+toOrderLine(): String
MenuItemOrder
-menuItem: MenuItem
-quantity: int
+MenuItemOrder(
menuItem: MenuItem, quantity: int )
+orderEntryPrice(): int
+toOrderLine(): String
Voucher
-voucherCode: String
-discount: int
-minimumOrderValue: int
+Voucher(
voucherCode: String, discount: int,
minimumOrderValue: int )
+orderEntryPrice(): int
+toOrderLine(): String
Figure 2: A UML class diagram of the Order class and its related classes and interfaces.
7
The OrderEntry interface
This interface has been written for you and you should not make any changes to it.
Any class that implements the OrderEntry interface represents an entry in a customers
order. As described below, this can be MenuItemOrder, which represents an order for one
or more units of a given MenuItem. Alternatively, this can be a Voucher, which will give
the customer money o their order if the total is high enough. You will need to implement
MenuItemOrder from scratch, but Voucher has been written for you and may provide a
useful example to help you.
The MenuItemOrder class
You will need to create this class and write all the specied methods. You may add any elds
or additional methods you require.
An object of type MenuItemOrder represents a customer’s desire to purchase one or more
units of a particular MenuItem. This class implements the OrderEntry interface.
The menuItem eld captures which MenuItem this order-entry corresponds to, and the
quantity eld captures the number of units desired. Key methods that you will need to
implement in this class are:
orderEntryPrice: returns the price in pence of the number of units specied by
quantity. This should include any multi-unit discounts specied by the MenuItem
object (see Section 2 for more details).
toOrderLine: returns a line of text showing (in the following order): the order-entry
price, the number of units, and the MenuItem name. The order-entry price should be
that calculated by orderEntryPrice.
The Voucher class
You do not have to make any changes to this class. The Voucher class implements the
OrderEntry class and represents a discount on the total price at the restaurant. A Voucher
object has three elds:
voucherCode, (a String) is the secret string required by the user to have the voucher
applied.
discount (an int) is the price reduction (in pence) to the overall bill when the voucher
is applied
minimumOrderValue (an int) is the minimum price (in pence) that the bill needs to
be before the voucher-code is accepted
Some details of the key methods are as follows:
A constructor that takes 3 arguments: voucherCode, discount, and minimumOrderValue
with their obvious meanings.
orderEntryPrice { returns the price adjustment to the bill, which is equal to minus
the discount. This is one of the methods promised to the OrderEntry interface.
8
toOrderLine { returns a line of text showing (in the following order): the price adjust-
ment, the word “Voucher”, and the voucher code. This is one of the methods promised
to the OrderEntry interface.
This information is provided for information only. You do not need to edit this class.
Look at the code or Figure 2 for more details.
The Order class
Order is a simple class for holding a customer’s order in terms of a collection of OrderItems.
It should display this order to screen, calculate the total price and do so taking account of
any discounts. Key methods that you will need to implement in this class are:
orderMenuItem: adds one or more units of a MenuItem to the Order. The input
argument newItem represents the MenuItem desired, and the input quantity represents
the number of units of this MenuItem to add. If this MenuItem has not yet been added
to the Order, then it should add a new MenuItemOrder to the entries eld. If this
MenuItem has previously been added to the Order then this method should increase
the quantity of that MenuItemOrder appropriately.
Hint: To check whether the input MenuItem already exists in Order, you will need to
compare the id of the MenuItem with every OrderEntry in entries that has actual type
MenuItemOrder. To do this, you will nd the instanceof keyword and downcasting
helpful. You will also nd the idMatches method from MenuItem helpful.
addDiscountVoucher: takes two arguments: voucherCode (a String), and voucher
(a Voucher), and returns a boolean. This should check both whether voucherCode
matches the code stored in voucher, and whether the current total order price is larger
than the minimumOrderPrice of voucher. If both conditions are true it should return
true. Otherwise, it should return false.
calculateTotal: takes no arguments and returns the total-price of the current order
(in pence), taking account of any discounts applied.
A constructor and the toString method has been implemented for you.
4 Provided Code
If you go to moodle, you can access a local copy of some support code. You should use
this code as a starting point for your system, but you will need to write additional les, e.g.
classes etc, for your system. It is important that your nal code compiles, and non-compiling
code will be penalised.
There is more than one way to solve this problem, and where you meet the specication
you will be given credit up to a maximum of 80%. Additional marks will be given for coding
style and comments, up to a maximum of 20%. This includes, but is not limited to: good
names for variables, appropriate use of control ow (e.g. for loops and if statements),
meaningful and appropriate comments, minimising duplication of code, appropriate helper
methods, and consistent formatting of code.
9
INST2002 Programming 2:
INST2002 Programming 2:
This assessment forms part of your degree assessment. It must be done entirely
on your own from start to nish:
You must not collaborate or work with other students at any stage.
You must not send or show other students your answers.
You must not ask other students for help, or ask to see their answers. As well as being
against regulations, this is unfair to the other student concerned, since it may lead to
them being accused of plagiarism.
You must not seek help from friends, relatives, or online discussion groups other than
the moodle forum for INST2002
If you think any of the description of the task below is ambiguous or unclear, please
post to the moodle forum, explaining what your concerns are, or raise it in person with
your lecturer, Luke Dickens, or a INST2002 lab demonstrator.
If you are unsure of any of the above points, please post your concern to the moodle
forum.
Finally, if there is any reason you do not think you can complete this assessment in
the alloted time, you should either make a formal request for an extension with your
home department, or discuss your reasons with the INST2002 lecturer, Luke Dickens at
l.dickens@ucl.ac.uk.
1 A Fast-Food Restaurant Menu System
Imagine that you are asked to write code to support an automated system for taking fast-
food restaurant orders, and to implement this for a particular fast-food restaurant of your
chosing. The main class RestaurantProg runs a simple interactive interface for a user: to
see menu items available to them at your fast food restaurant; to select one or more menu
items and add them to their order; and to see a running total price of their order, which
1
accounts for any discounts. Initially, RestaurantProg will only print a menu to screen. Until
you complete Section 2, you do not need to edit RestaurantProg. When you get to Section
3, you should uncomment the remaining code in RestaurantProg.
You have also been given a class Prices which gives you a simple way of converting int
prices into Strings. You do not need to edit this class.
You should begin by completing the implementation of Menu, MenuItem and the sub-
classes of MenuItem, the requirements are described in more detail in Section 2. After
which, you should attempt to implement Order, OrderEntry and the implementing classes
of OrderEntry, the requirements are described in more detail in Section 3.
2 Creating the Menu
A menu can contain dierent kinds of menu items, including main dishes, supplementary
dishes and drinks. To capture this, you should complete the implementation of the Menu and
MenuItem classes, as well as writing two additional classes MainDish and SupplementaryDish
(each extends the MenuItem abstract class). The class Drink has already been implemented
for you, and also extends the MenuItem abstract class.
You will need to write MainDish and SupplementaryDish from scratch. You can use
Drink as an example of how to do so. However, you need to decide whether MainDish
and SupplementaryDish are direct subclasses or whether you should structure the class
hierarchy dierently. Once you have implemented the classes in the section, you should be
able to compile and run the code, and it will create an example menu then print it to the
screen.
Look at the UML class diagram in Figure 1. This should the classes relevant to this
part of the coursework. The green classes have already been implemented for you, but the
yellow classes will require some implementation from you. In particular, you will need to
implement MainDish and SupplementaryDish from scratch.
The MenuItem class
You do not have to make any changes to this class. MenuItem is an abstract class that
represents items that can appear on the menu. Key methods in this class are:
A constructor that takes 3 arguments: id, name and unitPrice. Here id is the two
character String used to uniquely identify each MenuItem, name is a String holding
a short name of the item, and unitPrice is an int holding the price for a single unit
of the item.
getPrice { an abstract method. This takes a single int input units and has int
return type. Concrete subclasses of MenuItem should implement getPrice so that it
returns the price, in pence, of a given number of units of the item. This should take
account of any multi-unit discounts available for this MenuItem (see below for more
details).
toMenuLine { an abstract method. Concrete subclasses of MenuItem should imple-
ment toMenuLine so that it returns a line of text showing the product id, name and
various other details for the item (see below for more details).
2
Menu
-items: List<MenuItem>
+addMenuItem(item: MenuItem) : void
+isExistingItem(testId: String): boolean
+getItem(requestedId: String): MenuItem
+createExampleMenu(): Menu
MenuItem
-id: String
-name: String
-unitPrice: int
+getId() : String
+getName() : String
+getPaddedName() : String
+idMatches(testId: String) : boolean
+getPrice(units: int): int
+toMenuLine(): String
? ? ? ?
SupplementaryDish
???
+getPrice(units: int) : int
+toMenuLine(): String
MainDish
???
+getPrice(units: int) : int
+toMenuLine(): String
Drink
volume: int
+getPrice(units: int) : int
+toMenuLine(): String
Figure 1: A UML class diagram of the Menu class and its related classes and interfaces.
3
idMatches { a method that takes a single String argument, testId, and returns true
if this matches the id of the MenuItem, and false otherwise.
The above methods are already implemented. Additionally, the standard getter meth-
ods, and the method getPaddedName have also been implemented for you. getPaddedName
produces a xed length string (24 characters) containing the MenuItem’s name, and is to
help you write the toMenuLine method. There is no need to edit this class.
The MainDish class
You will need to create this class and write all the specied methods. You may add any
elds or additional methods you require. MainDish is a concrete subclass of MenuItem that
represents main-dishes at the restaurant. As well as having an id, name and unit-price,
a MainDish also records whether the dish is vegetarian or not. You must implement the
constructor, an isVegi method, and the two abstract methods of MenuItem: getPrice and
toMenuLine. The details of the required implementation are as follows:
A constructor that takes 4 arguments: id, name, unitPrice and vegetarian. Here
id, name, and unitPrice have the same meaning as in MenuItem. vegetarian is true
if the dish is vegetarian, and false otherwise.
isVegi { a simple getter method, this returns true if the dish is vegetarian, and false
otherwise.
getPrice { This overrides the corresponding abstract method in MenuItem. It takes
a single int input, units, and returns the price, in pence, of the given number of
units of the main dish. Main-dishes have multi-unit discounts: all main dishes can be
produced in single, double or triple portions respectively costing 1, 1:5 and 2 times the
unitPrice. If more than one dish is requested, the customer is given as many triple
portions as possible, and the remainder made up with a double or single portion. For
instance, if 8 portions are requested, the customer will be charged for 2 triple portions,
and 1 double portion.
toMenuLine { This overrides the corresponding abstract method in MenuItem. It
takes no input arguments, and returns a line of text showing (in the following order):
the product id, the name, a v if it is vegetarian and the price for a single, double and
triple dish. For instance, the code:
MainDish main1 = MainDish (“01″, ” Chicken Tikka “, 450 , false );
MainDish main2 = MainDish (“07″, ” Mixed Vegetable Curry “, 400 , false );
System . out. println ( main1 . toMenuLine ());
System . out. println ( main2 . toMenuLine ());
should produce output similar to:
01: Chicken Tikka 1 at 4.50 , 2 at 6.75 , 3 at 9.00
07: Mixed Vegetable Curry v 1 at 4.00 , 2 at 6.00 , 3 at 8.00
4
The SupplementaryDish class
You will need to create this class and write all the specied methods. You may add any elds
or additional methods you require. SupplementaryDish is a concrete subclass of MenuItem
that represents supplementary-dishes at the restaurant, such as rice and bread dishes. This
is very similar to the MainDish class, having an id, name and unit-price, as well as recording
whether the dish is vegetarian or not. As before, youmust provide a constructor, an isVegi
method, and implementations of the two abstract methods: getPrice and toMenuLine. The
details of the required implementation are as follows:
A constructor that takes 4 arguments: id, name, unitPrice and vegetarian. All
inputs have the same meaning as in MainDish.
isVegi { This has the same meaning as in MainDish.
getPrice { This overrides the corresponding abstract method in MenuItem. It takes a
single int input, units, and returns the price, in pence, of the given number of units
of the supplementary dish. Supplementary-dishes have multi-unit discounts: the rst
unit ordered is charged at the unitPrice, subsequent units are charged at 80% of the
unitPrice. For example, if the unitPrice is 1:00, then 1 unit is 1:00, 2 units are 1:80,
3 units are 2:60 and so on.
toMenuLine { This overrides the corresponding abstract method in MenuItem. It
takes no input arguments, and returns a line of text showing (in the following order):
the product id, the name, a v if it is vegetarian, the price for the rst unit then the
price for subsequent units. For instance, the code:
SupplementaryDish supp1 = SupplementaryDish (
“12”, ” Plain Naan “, 80, false );
SupplementaryDish supp2 = SupplementaryDish (
“13”, ” Keema Naan “, 200 , false );
System . out. println ( supp1 . toMenuLine ());
System . out. println ( supp2 . toMenuLine ());
should produce output similar to:
12: Plain Naan v 0.80 for 1, then 0.64 each
13: Keema Naan 2.00 for 1, then 1.60 each
The Drink class
You do not have to make any changes to this class. Drink is a concrete subclass of MenuItem
that represents drinks at the restaurant. As well as inheriting an id, name and unit-price, a
Drink also records its volume as an int. Some details of the key methods are as follows:
A constructor that takes 4 arguments: id, name, unitPrice and volume. Here id,
name, and unitPrice have the same meaning as in MenuItem. volume is the volume
of the drink in millilitres.
5
getVolume { a simple getter method, this returns the volume of the drink.
getPrice { This overrides the corresponding abstract method in MenuItem. It takes a
single int input, units, and returns the price, in pence, of the given number of units
of the drink. There are no multi-unit discounts available for drinks, instead each unit
is charged at the unit-price.
toMenuLine { This overrides the corresponding abstract method in MenuItem. It
takes no input arguments, and returns a line of text showing (in the following order):
the product id, the name, the volume and the unit price.
This information is provided for information only. You do not need to edit this class.
Look at the code or Figure 1 for more details.
The Menu class
You will need to edit this class. You may add any elds or additional methods you require.
Menu is a simple class for holding a collection of MenuItems, displaying them to screen,
and selecting them based on their ids. Key methods that you will need to implement in this
class are:
isExistingItem: returns true if a MenuItem in items has the same id as the input
testId.
getItem { this gets an existing MenuItem whose id matches the input requestedId.
If no such MenuItem appears in items then this method should throw an Exception.
addMenuItem { this takes a MenuItem as input, and if there is no MenuItem already
stored in items with the same id, it should add this to the items eld . The method
should throw an Exception when the id of the new MenuItem matches the id of an
existing MenuItem.
createExampleMenu { this is a static method that creates a new Menu object, and pop-
ulates it with MainDish, SupplementaryDish and Drink objects. You should choose
a name for your restaurant, and add at least 4 main dishes, 3 supplementary dishes
and 2 drinks, remember to include vegetarian and non-vegitarian dishes. There are
some examples of main-dishes, supplementary-dishes and drinks being created already
in this method, please replace these with your own menu-items.
You will need to edit all the methods in the above list. A constructor and the
toString method has been implemented for you.
3 A customer’s order
Do not attempt this part until you have implemented the classes required by Section 2.
You should now implement the classes that will allow customers to order items from the
menu, and to keep track of these orders. Begin by looking at Figure 2. The classes in yellow
will require some implementation from you. Those in green have been provided for you, and
do not need any changes. To test your changes in this section you should uncomment the
remaining code in RestaurantProg.
6
Order
-entries: List<OrderEntry>
+Order()
+orderMenuItem(
newItem: MenuItem, quantity: int) : void
+addDiscountVoucher(
voucherCode: String, voucher: Voucher) : boolean
+calculateTotal() : int
+toOrderLine() : String
<<interface>>
OrderEntry
+orderEntryPrice(): int
+toOrderLine(): String
MenuItemOrder
-menuItem: MenuItem
-quantity: int
+MenuItemOrder(
menuItem: MenuItem, quantity: int )
+orderEntryPrice(): int
+toOrderLine(): String
Voucher
-voucherCode: String
-discount: int
-minimumOrderValue: int
+Voucher(
voucherCode: String, discount: int,
minimumOrderValue: int )
+orderEntryPrice(): int
+toOrderLine(): String
Figure 2: A UML class diagram of the Order class and its related classes and interfaces.
7
The OrderEntry interface
This interface has been written for you and you should not make any changes to it.
Any class that implements the OrderEntry interface represents an entry in a customers
order. As described below, this can be MenuItemOrder, which represents an order for one
or more units of a given MenuItem. Alternatively, this can be a Voucher, which will give
the customer money o their order if the total is high enough. You will need to implement
MenuItemOrder from scratch, but Voucher has been written for you and may provide a
useful example to help you.
The MenuItemOrder class
You will need to create this class and write all the specied methods. You may add any elds
or additional methods you require.
An object of type MenuItemOrder represents a customer’s desire to purchase one or more
units of a particular MenuItem. This class implements the OrderEntry interface.
The menuItem eld captures which MenuItem this order-entry corresponds to, and the
quantity eld captures the number of units desired. Key methods that you will need to
implement in this class are:
orderEntryPrice: returns the price in pence of the number of units specied by
quantity. This should include any multi-unit discounts specied by the MenuItem
object (see Section 2 for more details).
toOrderLine: returns a line of text showing (in the following order): the order-entry
price, the number of units, and the MenuItem name. The order-entry price should be
that calculated by orderEntryPrice.
The Voucher class
You do not have to make any changes to this class. The Voucher class implements the
OrderEntry class and represents a discount on the total price at the restaurant. A Voucher
object has three elds:
voucherCode, (a String) is the secret string required by the user to have the voucher
applied.
discount (an int) is the price reduction (in pence) to the overall bill when the voucher
is applied
minimumOrderValue (an int) is the minimum price (in pence) that the bill needs to
be before the voucher-code is accepted
Some details of the key methods are as follows:
A constructor that takes 3 arguments: voucherCode, discount, and minimumOrderValue
with their obvious meanings.
orderEntryPrice { returns the price adjustment to the bill, which is equal to minus
the discount. This is one of the methods promised to the OrderEntry interface.
8
toOrderLine { returns a line of text showing (in the following order): the price adjust-
ment, the word “Voucher”, and the voucher code. This is one of the methods promised
to the OrderEntry interface.
This information is provided for information only. You do not need to edit this class.
Look at the code or Figure 2 for more details.
The Order class
Order is a simple class for holding a customer’s order in terms of a collection of OrderItems.
It should display this order to screen, calculate the total price and do so taking account of
any discounts. Key methods that you will need to implement in this class are:
orderMenuItem: adds one or more units of a MenuItem to the Order. The input
argument newItem represents the MenuItem desired, and the input quantity represents
the number of units of this MenuItem to add. If this MenuItem has not yet been added
to the Order, then it should add a new MenuItemOrder to the entries eld. If this
MenuItem has previously been added to the Order then this method should increase
the quantity of that MenuItemOrder appropriately.
Hint: To check whether the input MenuItem already exists in Order, you will need to
compare the id of the MenuItem with every OrderEntry in entries that has actual type
MenuItemOrder. To do this, you will nd the instanceof keyword and downcasting
helpful. You will also nd the idMatches method from MenuItem helpful.
addDiscountVoucher: takes two arguments: voucherCode (a String), and voucher
(a Voucher), and returns a boolean. This should check both whether voucherCode
matches the code stored in voucher, and whether the current total order price is larger
than the minimumOrderPrice of voucher. If both conditions are true it should return
true. Otherwise, it should return false.
calculateTotal: takes no arguments and returns the total-price of the current order
(in pence), taking account of any discounts applied.
A constructor and the toString method has been implemented for you.
4 Provided Code
If you go to moodle, you can access a local copy of some support code. You should use
this code as a starting point for your system, but you will need to write additional les, e.g.
classes etc, for your system. It is important that your nal code compiles, and non-compiling
code will be penalised.
There is more than one way to solve this problem, and where you meet the specication
you will be given credit up to a maximum of 80%. Additional marks will be given for coding
style and comments, up to a maximum of 20%. This includes, but is not limited to: good
names for variables, appropriate use of control ow (e.g. for loops and if statements),
meaningful and appropriate comments, minimising duplication of code, appropriate helper
methods, and consistent formatting of code.
9