INST2002 Programming 2: Coursework Specification

Important Notice

INST2002 Programming 2: Coursework Specification

Set by: Luke Dickens

Available from 15th December, 2015 Due at 2pm on 11th January, 2015

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, 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 di↵erent 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 di↵erently. 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

????

Figure 1: A UML class diagram of the Menu class and its related classes and interfaces.

MainDish

???

+getPrice(units: int) : int +toMenuLine(): String

SupplementaryDish

???

+getPrice(units: int) : int +toMenuLine(): String

Drink

volume: int

+getPrice(units: int) : int +toMenuLine(): String

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 fixed 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 specified methods. You may add any fields 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:

    should produce output similar to:

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());

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 specified methods. You may add any fields 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, you must 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 first 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 first unit then the price for subsequent units. For instance, the code:

    should produce output similar to:

    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.

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());

12: Plain Naan v 0.80 for 1, then 0.64 each 13: Keema Naan 2.00 for 1, then 1.60 each

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 fields 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 field . 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

-entries: List<OrderEntry>

Order

+Order() +orderMenuItem(

newItem: MenuItem, quantity: int) : void +addDiscountVoucher(

voucherCode: String, voucher: Voucher) : boolean +calculateTotal() : int
+toOrderLine() : String

<<interface>> OrderEntry

+orderEntryPrice(): int +toOrderLine(): String

MenuItemOrder

Voucher

-menuItem: MenuItem -quantity: int

-voucherCode: String -discount: int -minimumOrderValue: int

+MenuItemOrder(
menuItem: MenuItem, quantity: int )

+orderEntryPrice(): int +toOrderLine(): String

+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 specified methods. You may add any fields 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 field captures which MenuItem this order-entry corresponds to, and the quantity field 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 specified by quantity. This should include any multi-unit discounts specified 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 fields:

  • 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:

4

  • 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 field. 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 find the instanceof keyword and downcasting helpful. You will also find 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. 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 files, e.g. classes etc, for your system. It is important that your final code compiles, and non-compiling code will be penalised.

There is more than one way to solve this problem, and where you meet the specification 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 flow (e.g. for loops and if statements), meaningful and appropriate comments, minimising duplication of code, appropriate helper methods, and consistent formatting of code.

9