This page lists the milestone requirements for Milestone 3 of the CC 410 Restaurant Project. Read the requirements carefully and discuss any questions with the instructors or TAs.
The CC 410 Restaurant Project project for this semester is centered around building a point of sale (POS) system for a fictional restaurant named Starfleet Subs, based in the Star Trek universe.
The third milestone involves refactoring our code to take advantage of inheritance and the use of interfaces. We’ll also need to update our documentation and unit tests accordingly.
Warning
This project is the first that requires ALL general requirements introduced in the “Hello Real World” project. Read this section carefully to see what is required for this particular milestone.
This milestone must follow these professional coding standards:
__init__.py
and __main__.py
are exempt.application
plugin. The project should compile without errors. You may include a main class in a separate package for testing purposes only.flake8-docstrings
and pep8-naming
plugins. Code should conform to PEP 8 style with Google style docstrings.This milestone should include the following features:
starfleetsubs.data.menu.OrderItem
interface that is implemented by all entrée, side, and drink classes
starfleetsubs.data.entrees.Entree
base classstarfleetsubs.data.sides.Side
base classstarfleetsubs.data.drinks.Drink
base classstarfleetsubs.data.menu.Menu
that contains the full menu
Menu
class should containOrderItem
interfaceMenu
and OrderItem
should report near 100% code coverage.Menu
to confirm that each possible menu item is present in the menu.Completing this project is estimated to require 3-8 hours.
Tip
A rough estimate for this milestone would be around 1000 lines of new or updated code, and around 500 lines of redundant code removed. It could vary widely based on how you choose to implement the inheritance between the base classes and the interface. My model solution for this milestone now contains 526 unit tests in total. -Russ
This assignment will be graded based on the rubric below:
OrderItem
Interface - 25%Entree
Base Class - 10%Side
Base Class - 10%Drink
Base Class - 10%Menu
Class - 20%Menu
Unit Tests - 10%The following deductions apply:
This is not an exhaustive list of possible deductions. The instructors will strive to provide reasonable and fair grading, but we can’t predict all possible defects. It is up to the student to ensure that the project is complete and correct before submission.
Submit this assignment by creating a release on GitHub and uploading the release URL to the assignment on Canvas. You should not submit this Codio project or mark it as complete in Codio, in case you need to come back to it and make changes later.
The starfleetsubs.data.menu.OrderItem
class should be created as an interface that can be implemented by all other menu items. It should contain the following elements as abstract methods/properties:
Each menu item (entrées, sides, and drinks) should be refactored to implement this interface. This will require some changes:
Entree
base class.Side
base class.Accordingly, the unit tests for some of these classes will need updated, as discussed below.
Each of the three types of menu items should directly inherit from a new abstract base class. These classes should not be instantiated!
starfleetsubs.data.entrees.Entree
is the base class for all entrée items. It should include the following elements that are common to all entrée classes:
starfleetsubs.data.sides.Side
is the base class for all side items. It should include the following elements that are common to all side classes:
starfleetsubs.data.drinks.Drink
is the base class for all drink items. It should include the following elements that are common to all drink classes:
Tip
You may choose to implement the OrderItem
interface on the three base classes described below, which will then be inherited by each menu item, instead of explicitly implementing the interface on each menu item itself. Some of the elements described on these base classes are already defined in the OrderItem
interface, so if you implement the interface at the base class level you do not need to redefine the abstract methods from the interface within the abstract base classes. Either approach is valid!
If you choose to inherit from the OrderItem
interface in the base classes in Python, the base class should not inherit from ABC
- that is already covered as part of the interface. If you do, Mypy will present an error stating that it “cannot determine consistent method resolution order.”
You may also need to refactor some private
attributes (with double underscores in Python) to protected
attributes (single underscores in Python) as they move from the subclass to the superclass. In Java, these are just attributes as expected. In Python, it is simplest to declare those in the constructor of the superclass (such as self._size = Size.SMALL
), then make sure you call that constructor using super().__init__()
in the subclass' constructor.
The starfleetsubs.data.menu.Menu
class should be a class that has static getter methods for these four elements:
entrees
- a list of OrderItem
elements containing an instance of all available entrées (7 in total).sides
- a list of OrderItem
elements containing an instance of all available sides. Since each side is available in three sizes, the list should include an instance of all three sizes of each side item (12 in total).drinks
- a list of OrderItem
elements containing an instance of all available drinks. Since each drink is available in three sizes, the list should include an instance of all three sizes of each drink item (15 in total).fullmenu
- a combined list of all menu items (34 in total).In Java, these lists should use a subclass of the List interface. In Python, these methods should use the built-in Python list data type. Since they are static methods, they cannot be constructed as Python properties using the @property
decorator.
The following updates must be made to the existing unit tests in this project to accommodate these code changes:
Add:
InheritsFromEntree()
- check if a given object inherits from the base Entree
class.ImplementsOrderItem()
- check if a given object implements the interface OrderItem
.ChangeCondimentSetsSpecialInstructions(Condiment)
- for each condiment, check that changing it from and to the default value will add and remove the correct item from the SpecialInstructions
list.Update:
SpecialInstructionsInitiallyEmpty()
should be renamed SpecialInstructionsInitiallyCondiments()
and should now verify that the initial set of condiments is in the special instructions list.Add:
InheritsFromSide()
- check if a given object inherits from the base Side
class.ImplementsOrderItem()
- check if a given object implements the interface OrderItem
.SpecialInstructionsEmpty()
- check that the Special Instructions list is always empty.Add:
InheritsFromDrink()
- check if a given object inherits from the base Drink
class.ImplementsOrderItem()
- check if a given object implements the interface OrderItem
.Tip
To check for type compatibility, use the object instanceof Class
operator in Java, or the isinstance(object, Class)
method in Python as part of an assertion statement. Hamcrest also includes a few matchers for this, such as isA
(Java) or instance_of()
(Python).
Create a new test class for the Menu
static class:
IncludesAllEntrees()
- test that the entrees
list contains an instance of each entrée classIncludesAllSides()
- test that the sides
list contains an instance of each side class for each sizeIncludesAllDrinks()
- test that the drinks
list contains an instance of each drink class for each sizeIncludesAllItems()
- test that the fullmenu
list contains an instance of every menu item.