Project Milestones
Small steps along the path toward project completion!
Small steps along the path toward project completion!
This page lists the milestone requirements for the Final Project in CC 410. Read the requirements carefully and discuss any questions with the instructors or TAs.
This assignment allow students to exercise their programming skills by building a project of their own design. Ideally, the project will be something related to the student’s personal interests or area of study. All the requirements listed below are considered flexible and can be adapted to fit the individual project and student.
A complete final project should include the following features:
gradle
or tox
) and test frameworks. The goal is to use the tools learned throughout the semester to build a different project and focus on the design of the code, not learning new tools or languages.Completing this project is estimated to require 25-50 hours depending on familiarity with the tools involved. Spread across the entire semester, this equates to roughly 1-3 hours of work each week. This project should be roughly 1/4 to 1/3 the size and scope of the semester-long restaurant project.
The final project in this course will consist of several different milestones. Each milestone will require students to schedule a short meeting with the instructor or GTA to review the project as it stands and get feedback. The milestones are meant to roughly correspond to content being covered in this class.
README
file that describes your project, including how to compile and run it.README
file as well.This assignment will be graded following the concept of criterion grading, an approach that only assigns points for completing the full requirements. However, the requirements will be brief and straightforward, and will be treated as such. Projects that meet the requirements listed above will, at a minimum, earn a passing grade of 60%.
Projects that go above and beyond the requirements in various ways will be graded higher. In general, the goal of this project is to build a program that is interesting and engaging to the user, but also demonstrates the student’s ability to develop professional code. So, projects that are easy to use, interesting, demonstrate good design and coding standards, and fit well within the student’s defined interests are likely to earn additional points.
Throughout the semester, students will have a chance to work with an instructor or GTA to get feedback on the project while it is being developed. These meetings allow the student to get information about which requirements have been met and which ones have not, as well as general overview of the project from the reviewer.
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.
This page lists the milestone requirements for the Example 1 - Hello Real World project. Read the requirements carefully and discuss any questions with the instructors or TAs.
This assignment mimics the traditional “Hello World” project that most programmers learn as their first program, but done following professional coding standards and guidelines. In effect, this is how a professional coder would write “Hello World” as a project for work.
This project should include the following features:
HelloWorld
class that contains a main
method.
main
method should print “Hello World” if no command line arguments are received.main
method should print “Hello {arg}” if a command line argument is received.HelloWorld
class, properly testing both with and without command-line arguments..py
files should also include a file docstring, including __init__.py
and __main__.py
files for packages.HelloWorld
class must include explicit data types
HelloWorld
class must not use Any
as a type.Completing this project is estimated to require 2-5 hours depending on familiarity with the tools involved.
This assignment will be graded based on the rubric below:
HelloWorld
class - 30%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.
This page lists the milestone requirements for Milestone 1 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 Game Grub, offering food of all kinds to celebrate our love of games of all kinds.
This first milestone involves building the classes that represent items on the restaurant’s menu. In a traditional Model-View-Controller software design pattern, these classes would make up the core of the model. This content should be mostly review of concepts learned in prior CC courses with the addition of enumerations (enums). It should not be particularly difficult, but it may be repetitive and time consuming.
Specifically, we’ll focus primarily on data encapsulation by storing attributes about each menu item in the class. We’ll also learn how to combine state and behavior by modifying the string representation of the object based on the current state, or the combined values stored in the attributes.
In future milestones, we’ll focus on adding inheritance to simplify the code and structure in these classes. We’ll also add proper unit tests and documentation to these classes. For now, our only focus is on building the classes themselves.
The first couple of milestones only require a subset of the 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.This milestone should include the following features:
gamegrub.data.entrees
packagegamegrub.data.sides
packagegamegrub.data.drinks
packagegamegrub.data.enums
packageSee the Game Grub Menu section below for descriptions of what each class should contain.
Python - these files should include complete type annotations and achieve a low imprecision percentage in Mypy using strict type checking.
In my testing, the only imprecision in type checking should be the first line of the __eq__
method since it must accept an imprecise object
type until the isinstance()
method call. It will also mark the @property.setter
annotations, but they don’t count toward the imprecision total and can be ignored. The total imprecision should be less than 5% overall, and will probably be less than 2% in most cases. -Russ
Completing this project is estimated to require 3-8 hours.
In my testing, this milestone requires around 1000-1500 lines of pure code without documentation, or around 2000-2500 lines including documentation comments that will be included as part of milestone 2. Much of the code can be carefully copy-pasted between files with similar attributes. My best suggestion is to do the enumerations first, then pick one of the complex entrees and start there. Once you have the entrees all working, the sides and drinks are pretty easy and use much of the same structure. -Russ
This assignment will be graded based on the rubric below:
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.
As part of the grading of all assignments in this course, I will be doing a deep dive into a few classes in your code. This will include leaving detailed comments on code style and format in GitHub. I will usually choose various classes to review at random, and any issues found in that class will be verified in other classes of the same type. - Russ
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.
our motto: play fair, eat well
Each attribute described below should be implemented as a private variable within the class. Most attributes will also include a getter method, and sometimes a setter method, following this naming scheme (using Price as an example):
price
attribute would have a getPrice
getter and setPrice
setter method.__price
attribute would have a getter and setter named price
implemented as a Python Property.Each entree should be stored in an appropriately named class in the gamegrub.data.entrees
package. Each entree should include an attribute for the following data:
Base
value (see below). It should have a getter and setter method.Topping
values (see below).
In addition, each entree should have the ability to return the following data through an appropriate getter method. The data may be stored as attributes or hard coded directly into the method.
double
or Python float
value representing the base price of the item plus any upcharge associated with the chosen Base value.int
value representing the number of calories associated with the item.String
values or a Python list of str
values.
Unfortunately, the Java clone()
methods can cause an unchecked cast exception when used on Java Collections classes with generics. See this StackOverflow question for a discussion of how to get around that using a copy constructor.
Each entree class should also override the default string representation method (toString()
in Java or __str__()
in Python) and return a string that properly describes the entree. The string should be formatted as “{entree name} on {base}”, such as “Clue Chili on Spaghetti”.
It should also override the default equality method (equals()
in Java or __eq__()
in Python). Two items should be considered equal only if the values of all attributes are equal.
Each entree description will include a list of ingredients included on the entree. Those ingredients should be represented using Boolean attributes that are set to true
by default, with appropriate getter and setter methods. Changing any of these to false
will cause a “Hold {ingredient}” message, such as “Hold Sauce”, to be added to the Instructions list. Likewise, changing it back to true
will remove the appropriate message. If all ingredients are at their default values, the Instructions list should be empty.
Each entree will be served on a particular Default Base, and will include a default set of Toppings. Those attributes should be populated appropriately in the constructor for the entree. Changes to the Base and Toppings attributes will not affect the Instructions attribute at this time (we’ll add that later).
The number of Calories for a entree will remain constant, regardless of other attributes (we’ll just pretend that changing the base or toppings doesn’t change the number of calories).
The Price for a entree will change based on the value selected for the Base. Each entree will have a base price listed for the Default Base option. Other bases include an associated upcharge or discount, which must be adjusted.
This means that the prices shown on the menu already include the upcharge for the given default base. You may want to calculate and store a base price for the item by removing the upcharge from the menu price.
you’ll have to discover “whodunit” and created this twist on a classic
gamegrub.data.entrees.Clue
- The price is $10.45 and it is 1165 calories. Served on a Spaghetti Base. Ingredients: Spicy Beef, Chili, Red Sauce and Beans. Toppings: Onion, Cheese and Hot Sauce
stack them higher and higher until it all falls down
gamegrub.data.entrees.Jenga
- The price is $11.85 and it is 1470 calories. Served on a Chips Base. Ingredients: Spicy Beef, and Beans. Toppings: Onion, Cheese, Sour Cream, Hot Sauce and Guacamole
a refreshing dish perfect for a day on the water
gamegrub.data.entrees.Yahtzee
- The price is $15.25 and it is 785 calories. Served on a Rice Base. Ingredients: Tuna, Veggies, and Seaweed. Toppings: Guacamole, Soy Sauce, Hot Sauce and Crispy Strips
a hearty dish to checkmate any hunger
gamegrub.data.entrees.Chess
- The price is $13.65 and it is 1555 calories. Served on a Spaghetti Base. Ingredients: Crispy Chicken, and Red Sauce. Toppings: Cheese and Fresh Herbs
a true winner takes home everything
gamegrub.data.entrees.Monopoly
- The price is $18.65 and it is 1685 calories. Served on a Rice Base. Ingredients: Spicy Beef, Crispy Chicken, Beans, and Veggies. Toppings: Onion, Cheese, Hot Sauce, Sour Cream, Guacamole, and Crispy Strips
Each side should be stored in an appropriately named class in the gamegrub.data.sides
package. Each side should include an attribute for the following data:
Size
value (see below). It should have a getter and setter method.In addition, each side should have the ability to return the following data through an appropriate getter method. The data may be stored as attributes or hard coded directly into the method.
double
or Python float
value.int
value.Each side class should also override the default string representation method (toString()
in Java or __str__()
in Python) and return a string that properly describes the side. The string should be formatted as “{size} {side name}”, such as “Junior Potato Dice”.
It should also override the default equality method (equals()
in Java or __eq__()
in Python). Two items should be considered equal only if the values of all attributes are equal.
Each side description will include a Price and number of Calories for each Size. The sides will have a default size of Junior
.
a pile of d6 shaped taters, deep fried and tasty
gamegrub.data.sides.Dice
- Junior: $2.75 and 350 calories. Classic: $3.85 and 475 calories. Winner: $5.35 and 795 calories.
wheat breaded lamb skewers, baked in a wood-fired clay oven and sprinkled with salt ore - every resource in the game!
gamegrub.data.sides.Catan
- Junior: $4.45 and 530 calories. Classic: $6.85 and 815 calories. Winner: $8.65 and 1045 calories.
deep fried mac & cheese balls, but one has a spicy surprise - are you brave enough to risk it?
gamegrub.data.sides.Risk
- Junior: $3.95 and 480 calories. Classic: $5.15 and 755 calories. Winner: $6.95 and 940 calories.
Each drink should be stored in an appropriately named class in the gamegrub.data.drinks
package. Each drink should include an attribute for the following data:
Size
value (see below). It should have a getter and setter method.In addition, each drink should have the ability to return the following data through an appropriate getter method. The data may be stored as attributes or hard coded directly into the method.
double
or Python float
value.int
value. It should have a getter method.String
values or a Python list of str
values.
Each drink class should also override the default string representation method (toString()
in Java or __str__()
in Python) and return a string that properly describes the drink. The string should be formatted as “{size} {drink name}”, such as “Junior Candy Land Shake”.
It should also override the default equality method (equals()
in Java or __eq__()
in Python). Two items should be considered equal only if the values of all attributes are equal.
Each drink description may include a list of flavors that may be added. Those flavors should be represented using Boolean attributes that are set to false
by default, with appropriate getter and setter methods. Changing any of these to true
will cause a “Add {flavor}” message, such as “Add Cherry”, to be added to the Instructions list. Likewise, changing it back to false
will remove the appropriate message.
In addition, drinks may specify default flavors that should be represented using Boolean attributes that are set to true
by default, with appropriate getter and setter methods. Changing any of these to false
will cause a “Hold {flavor}” message, such as “Hold Coconut”, to be added to the Instructions list. Likewise, changing it back to true
will remove the appropriate message.
If all flavors are at their default values, the Instructions list should be empty.
Each drink description will include a Price and number of Calories for each Size. The drinks will have a default size of Junior
. Changes to the Size attribute will not affect the Instructions attribute.
a classic shake with all the candy!
gamegrub.data.drinks.Candy
- Flavors: Chocolate (default), Vanilla, and Strawberry. Junior: $5.75 and 770 calories. Classic: $7.45 and 1215 calories. Winner: $9.55 and 1465 calories.
soda fountain for all, no apologies needed
gamegrub.data.drinks.Sorry
- Flavors: Cola (default), Cherry, Grape, and Orange. Junior: $2.55 and 370 calories. Classic: $3.85 and 535 calories. Winner: $5.35 and 765 calories.
fuel for the brain to win the game
gamegrub.data.drinks.Cranium
- Flavors: Milk (default), Caramel, Chocolate, and Mint. Junior: $4.35 and 380 calories. Classic: $5.25 and 495 calories. Winner: $6.00 and 585 calories.
Each enumeration should be stored in an appropriately named class in the gamegrub.data.enums
package. Each enumeration class should also override the default string representation method (toString()
in Java or __str__()
in Python) and return a string that properly describes the item. Python developers may also wish to override the __repr__()
method to return this value as well.
an excellent start for a delicious meal
gamegrub.data.enums.Base
- Rice (add $1.00), Spaghetti (add $1.50) or Chips (add $2.00)
It is possible to create an enumeration that also stores additional data associated with each value, and then access that data through the enum value. You may be able to use this to simplify handling the upcharge for each base. Below are links to some sample code from later in this course that shows how to create such an enum and use that data.
strategies to win any game and fulfill your hunger
gamegrub.data.enums.Size
- Junior (Small), Classic (Medium), Winner (Large)
complete your meal and win the day
gamegrub.data.enums.Toppings
- Onions, Cheese, Hot Sauce, Sour Cream, Guacamole, Soy Sauce, Crispy Strips, Fresh Herbs
Special thanks to friends and family for inspiration and menu suggestions!
This page lists the milestone requirements for Milestone 2 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 Game Grub, offering food of all kinds to celebrate our love of games of all kinds.
The second milestone involves writing documentation and unit tests for our existing code base. Our goal is to adequately test each part of our code via unit tests, reaching 100% code coverage at a minimum. In addition, we’ll add all of the required documentation comments in our existing code.
The first couple of milestones only require a subset of the 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.This milestone should include the following features:
test
directory for the class it is testing.src
directory.java
or python
folder).Some quick tips from when I did this milestone:
PRICE = 0.50
attribute, and then use that value in your unit test. In that way, when you copy and paste unit test code, you can simply change the global attributes to match the item being tested. Many tests can be generalized in that way such that all entrees test classes share the same code for many tests, referring to global attributes that are changed in each class. The same works for drinks and sides.beans
or cherry
) can be done using reflection or metaprogramming, but I don’t recommend it. Since each ingredient is an individual attribute, generalization is very complex and prone to errors. Those tests were hard-coded for each individual ingredient in my solution.@pytest.mark.parametrize("base", Base)
.default
branches in switch statements across enums, which will be unreached in code coverage. This is fine, but a good reason to avoid switch statements, as you will never get 100% code coverage! I ended up changing my model solution to remove switch statements.-Russ
Completing this project is estimated to require 3-8 hours.
In my testing, this milestone requires around 3500-4000 lines of code (including very rudimentary documentation comments) in the unit tests directory. As with the prior milestone, much of the code can be carefully copy-pasted between files with similar attributes. My best suggestion is to pick one of the complex entrees and start there writing unit tests. Once you have the entrees all working, the sides and drinks are pretty easy and use much of the same structure. There are several hundred unit tests in my model solution. I ended up finding half a dozen errors in my model solution for milestone 1, showing the importance of unit testing! -Russ
This assignment will be graded based on the rubric below:
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.
As part of the grading of all assignments in this course, I will be doing a deep dive into a few classes in your code. This will include leaving detailed comments on code style and format in GitHub. I will usually choose various classes to review at random, and any issues found in that class will be verified in other classes of the same type. - Russ
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.
Each test class should contain unit tests for the following (this is not an exhaustive list, but should get close to 100% coverage):
Each test class should contain unit tests for the following (this is not an exhaustive list, but should get close to 100% coverage):
Each test class should contain unit tests for the following (this is not an exhaustive list, but should get close to 100% coverage):
Remember that unit tests should test a single unit of code. So, make sure your unit tests are as short and concise as possible to allow you to pinpoint individual errors.
Extra Credit: After writing all of the unit tests listed above, feel free to suggest any unit tests you feel are missing. Email your added tests to the course help email address and you may earn bug bounty points for your suggestions!
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 Game Grub, offering food of all kinds to celebrate our love of games of all kinds.
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.
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 should include the following features:
gamegrub.data.Item
interface that is implemented by all entree, side, and drink classes
gamegrub.data.entrees.Entree
base classgamegrub.data.sides.Side
base classgamegrub.data.drinks.Drink
base classgamegrub.data.menu.Menu
that contains the full menu
Menu
class should containItem
interfaceMenu
and Item
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.
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 about 100 more unit tests in total. -Russ
This assignment will be graded based on the rubric below:
Item
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.
As part of the grading of all assignments in this course, I will be doing a deep dive into a few classes in your code. This will include leaving detailed comments on code style and format in GitHub. I will usually choose various classes to review at random, and any issues found in that class will be verified in other classes of the same type. - Russ
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 gamegrub.data.Item
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 (entrees, sides, and drinks) should be refactored to implement this interface. This will require some changes:
Entree
base class. This also means that newly instantiated items should no longer have an empty Instructions list. However, it may be simpler to populate the list when it is requested instead of storing it.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!
gamegrub.data.entrees.Entree
is the base class for all entree items. It should include the following elements that are common to all entree classes:
gamegrub.data.sides.Side
is the base class for all side items. It should include the following elements that are common to all side classes:
gamegrub.data.drinks.Drink
is the base class for all drink items. It should include the following elements that are common to all drink classes:
You may choose to implement the Item
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 Item
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, though going through the base class makes things simpler down the road!
If you choose to inherit from the Item
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.JUNIOR
), then make sure you call that constructor using super().__init__()
in the subclass’ constructor.
The gamegrub.data.menu.Menu
class should be a class that has static, class-level getter methods for these four elements:
entrees
- a list of Item
elements containing an instance of all available entrees (5 in total).sides
- a list of Item
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 (9 in total).drinks
- a list of Item
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 (9 in total).fullmenu
- a combined list of all menu items (23 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:
Item
interfaceItem
interfaceItem
interfaceTo 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).
This page lists the milestone requirements for Milestone 4 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 Game Grub, offering food of all kinds to celebrate our love of games of all kinds.
The fourth milestone involves creating a class to track orders made at the restaurant, a class for combo meals, and more. It also includes many different design patterns to improve the structure of the code.
This assignment will add several new classes to the project
gamegrub.data.order.Order
- this class should represent a collection of Item
objects that make up an order.
Item
object is contained in the collection. Recall that this should use the identity test, not the equality test.Item
s, with methods to add and remove items.
OrderNumberSingleton
class discussed below. It should only include a getter.Order
objects.gamegrub.data.combo.Combo
- this class should implement the Item
interface, and represent a combo meal consisting of an entree, a side, and a drink.
Entree
instance - the entree in the comboSide
instance - the side in the comboDrink
instance - the drink in the combonull
or None
in the constructor to represent a combo yet to be configured.null
or None
. You may have a single method, or one for each attribute.Item
interface:
discount
Discount Applied” if all items in the combo are present. If not, this entry should not be included.null
or None
. The name will only be set by the ComboBuilder
class discussed below, but users will also be able to configure a custom combo via the GUI that does not include a name.null
or None
initially.null
or None
, it is considered equal if the matching attribute is also null
or None
.
equals()
method on a null
object will result in an exception. So, you’ll have to check if each attribute in this object is null
first. If so, and the other object’s attribute is not null
, then they are not equal. If this object’s attribute is not null
, you can safely call equals()
on it, regardless of the other object’s attribute.gamegrub.data.combo.ComboBuilder
- a class that implements the Builder Pattern and Factory Method Pattern to build the available combos described below.
Combo
object indicated by that string (the name of the combo).You don’t have to create individual classes for the builder pattern in the ComboBuilder
class - it is sufficient to just have a private method for building each combo in the class itself. The full Builder pattern is a bit too much boilerplate code for this simple use.
gamegrub.data.order.OrderNumberSingleton
- a class that implements the Singleton Pattern to generate new order numbers.
There will also be several updates to existing classes.
Menu
- update to include the following items:
ComboBuilder
class discussed below.All new and updated classes in this milestone should contain full documentation comments. Every method should be completely documented!
No new unit tests are required for this milestone. They will be added in the next milestone.
Completing this project is estimated to require 3-8 hours.
A rough estimate for this milestone would be around 1000 lines of new or updated code. -Russ
This assignment will be graded based on the rubric below:
Order
- 30%Combo
- 30%ComboBuilder
- 15%OrderNumberSingleton
- 15%Menu
class: 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.
As part of the grading of all assignments in this course, I will be doing a deep dive into a few classes in your code. This will include leaving detailed comments on code style and format in GitHub. I will usually choose various classes to review at random, and any issues found in that class will be verified in other classes of the same type. - Russ
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.
Jenga Nachos, Catan Skewers, Sorry Soda
Yahtzee Poke, Potato Dice, Candy Land Shake
Chess Chicken Parmesan, Risk Bites, Cranium Coffee
Monopoly Bowl, Potato Dice, Sorry Soda
This page lists the milestone requirements for Milestone 5 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 Game Grub, offering food of all kinds to celebrate our love of games of all kinds.
The fifth milestone involves writing unit tests for the order, combo, and associated classes created in the previous milestone. These unit tests will make extensive use of test doubles.
The following new classes should contain unit tests that achieve at or near 100% code coverage and adequately test all aspects of the class.
Order
Combo
ComboBuilder
OrderNumberSingleton
Test doubles must be used where noted in the discussion below. In general, any time a test refers to another class other than the one being tested, it should use a test double instead of an instance of that class.
In addition, some previous tests may need to be updated to match new requirements.
Menu
- add tests for combos and updated full menuOnce this milestone is complete, all classes in the following packages should have unit tests that achieve at or near 100% code coverage:
gamegrub.data.*
Completing this project is estimated to require 3-8 hours.
A rough estimate for this milestone would be around 2000 lines of new or updated code. -Russ
This assignment will be graded based on the rubric below:
Order
- 30%Combo
- 30%ComboBuilder
- 15%OrderNumberSingleton
- 15%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.
As part of the grading of all assignments in this course, I will be doing a deep dive into a few classes in your code. This will include leaving detailed comments on code style and format in GitHub. I will usually choose various classes to review at random, and any issues found in that class will be verified in other classes of the same type. - Russ
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.
This is a suggested list of unit tests you may wish to implement to test your new and updated classes in this milestone. You should be able to reach 100% code coverage in each of these classes.
equals()
is called. Place one in the order, and use them to confirm that contains
returns both true and false when given two items that are equal but not the same instance.OrderNumberSingleton
that returns a value for an order number, then instantiate an Order
and verify that it received the given order number.Order
instances, change the tax rate, and confirm that both use the new tax rate. This is best done by adding an item to each order and checking the tax
virtual attribute.null
or None
and handle that case properlynull
or None
Combo
instances, change the discount, and confirm that both use the new discount. This is best done by adding all items to each combo and checking the total price.For these tests, I recommend just checking the types of the entree, side, and drink items in the Combo returned, as well as the name, rather than using any test double objects. As before, you may wish to make these attributes visible to the test.
getNextOrderNumber()
several times and make sure each one is sequential.This page lists the milestone requirements for Milestone 6 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 Game Grub, offering food of all kinds to celebrate our love of games of all kinds.
The sixth milestone involves creating the various GUI windows and panels required for this project. The next milestone will involve adding functionality to these GUI elements beyond the ability to load different panels into the main window area.
This milestone should include the following features:
gamegrub.gui
package to store all GUI code.gamegrub.gui.entrees
package to store all GUI panels for entrees.gamegrub.gui.sides
package to store all GUI panels for sides.gamegrub.gui.drinks
package to store all GUI panels for drinks.gamegrub.Main
class that properly loads and displays the program’s GUI.gamegrub.gui.PrimaryWindow
class that represents the main GUI window.
gamegrub.gui.MenuPanel
class to represent the main ordering screen panel.
gamegrub.gui.OrderPanel
class to represent the sidebar panel containing a user’s order.
gamegrub.gui.entrees
package for each entree.
EntreePanel
class to reduce the amount of duplicate code.SidePanel
in the gamegrub.gui.sides
package.
Side
class instead of individual sides themselves. When the buttons on the menu are clicked, you’ll need to make sure an instance of the correct menu item is created.gamegrub.gui.drinks
package for each drink item.
DrinkPanel
class to reduce the amount of duplicate code.Each of the menu item panels should also implement the following functionality:
gamegrub.gui
package do require all appropriate documentation comments, and must be free of style errors. Every method must include full documentation comments.gamegrub.gui
package do not require unit tests at this time.gamegrub.gui
package do not require type hints in Python, though you may continue to use them if they are helpful. Any errors from Mypy originating in these classes will be ignored.gamegrub.gui
package and how all GUI classes are related. You should also show any links to the classes in the gamegrub.data
package, but you may choose to show simplified links between packages instead of individual classes. You do not have to include full details from classes in the gamegrub.data
packages.
gamegrub.gui.entrees
package are all related to similar classes in the gamegrub.data.entrees
package without listing the individual classes in that package.You are welcome to add additional methods to the existing content in the gamegrub.data
package. If so, make sure you include appropriate documentation, type checking and unit tests.
See below for a few sketches of what your GUI might look like.
You are encouraged to use the code from Example 6 as a basis for this GUI, or you may create a different design. There are no set requirements for the design other than what is listed above, and the overall focus in this milestone is on simply getting the content on the screen and the ability to move between the various panels. You are welcome to spend additional time on the design if desired, but focus on getting the the content on the screen before doing any design work.
Completing this project is estimated to require 3-8 hours.
A rough estimate for this milestone would be around 1500 lines of new code. It could vary widely based on how you choose to implement the various portions of the GUI. I was able to reuse many portions of the example project and expand on them to build this milestone. -Russ
This assignment will be graded based on the rubric below:
Main
class - 2%PrimaryWindow
class - 4%OrderPanel
class - 4%MenuPanel
class - 20%SidePanel
class - 5%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.
As part of the grading of all assignments in this course, I will be doing a deep dive into a few classes in your code. This will include leaving detailed comments on code style and format in GitHub. I will usually choose various classes to review at random, and any issues found in that class will be verified in other classes of the same type. For any GUI portions, I’ll also be testing the functionality of the GUI for each class under review. - Russ
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.
Below are some GUI sketches to help you visualize one possible GUI for a previous version of this project. You do not have to match this design at all, but this is at least a good starting point that you can reach based on what you learned in Example 6.
I chose to increase the default size of my GUI to 1024x740 pixels, as that made the buttons fit better into the window. - Russ
Here are a couple of helpful pieces of code that you may wish to use in your project.
In many cases, I found it easiest to create private or protected methods that will construct my GridBagConstraints
objects, either within the class I was working in or in a parent class in the case of entree and drink panels. Here’s an example:
/**
* Construct a GridBagConstraints object.
*
* @param y the y coordinate of the object
* @param start set anchor to LINE_START
* @return the constructed GridBagConstraints object
*/
protected GridBagConstraints makeGbc(int y, boolean start) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = y;
if (start) {
gbc.anchor = GridBagConstraints.LINE_START;
}
gbc.insets = new Insets(2, 2, 2, 2);
return gbc;
}
Then, when I want to place something in my layout using a GridBagConstraints
object build from this method, I can use this:
this.add(check, this.makeGbc(i++, true));
The biggest benefit to this approach is that I can easily adjust all of the buttons by changing this one method. This is a great example of the “Don’t Repeat Yourself” or DRY principle.
In many cases, I found it helpful to create a dictionary of settings that I’d like use with the grid()
method, and then pass that entire dictionary as keyword arguments to the method. I usually did this either in a helper method within the class itself, or in a parent class in the case of pizza and drink panels. Here’s an example:
def _grid_dict(self, row: int, sticky: str) -> Mapping[str, Any]:
"""Create a dictionary of settings.
Args:
row: the row for the item
sticky: the sticky settings
"""
settings: Dict[str, Union[str, int]] = dict()
settings["row"] = row
settings["column"] = 1
settings["padx"] = 2
settings["pady"] = 2
settings["sticky"] = sticky
return settings
Then, when I want to place something in my layout using the grid()
method with these settings, I can use this:
checkbutton.grid(**self._grid_dict(i, "W"))
Notice that I have to place two asterisks **
before the method. That tells Python to “unpack” the dictionary returned by that method so that it can be read as individual keyword parameters. A deeper explanation is found here.
The biggest benefit to this approach is that I can easily adjust all of the buttons by changing this one method. This is a great example of the “Don’t Repeat Yourself” or DRY principle.
I also had to tell Mypy to ignore the lambda expressions used in the MenuPanel
class, as it cannot properly determine the type of the lambda. You can do this by adding a # type: ignore
comment at the end of the offending line.
button = Button(master=side_frame, text=str(side),
command=lambda x=str(side): # type: ignore
self.action_performed(x))
If anyone is able to figure out exactly how to properly get Mypy to handle this, there are major Bug Bounty points available!
This page lists the milestone requirements for Milestone 7 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 Game Grub, offering food of all kinds to celebrate our love of games of all kinds.
The seventh milestone involves dealing with the various events generated by the GUI and constructing a list of items that represent an order.
Changes to the previous milestone:
OrderPanel
panel.OrderPanel
to a tree element (Java JTree
or tkinter Treeview
). See the associated example project for code you can use for this.See the updated GUI mockups below for some design ideas.
Once the entire project is working, you should observe the following behavior on the new tree element.
When an item is added to the tree element in the OrderPanel
, the following should happen:
It may be helpful to maintain a hash map or dictionary in the OrderPanel
class that associates nodes in the GUI tree element with the actual Item
instances that they represent. This is in addition to the Order
object they will be stored in (added in a later milestone).
When the Save button in any of the entree, side, or drink panels is clicked, the following should happen:
OrderPanel
if it is a new item, or the item should be updated if it is being edited.PrimaryWindow
should be replaced with the MenuPanel
(this was part of the previous milestone).When the Cancel button in any of the entree, side, or drink panels is clicked, the following should happen:
PrimaryWindow
should be replaced with the OrderPanel
(this was part of the previous milestone for the Save button, and the code is similar).When the Edit button in the OrderPanel
is clicked, the following should happen:
Item
that is currently selected should be determined. If the selection is an child of that item, the code should work upwards in the tree to find the related Item
.PrimaryWindow
and populated with the current data from the item (most of this should be present from the previous milestone, but much of it may be untested at this point).When the Delete button in the SidebarPanel
is clicked, the following should happen:
Item
that is currently selected should be determined. If the selection is an child of that item, the code should work upwards in the tree to find the related Item
.OrderPanel
class.Unit tests should be added to the corresponding test package for the following classes:
gamegrub.gui.entrees
gamegrub.gui.drinks
gamegrub.gui.sides
See below for a list of suggested unit tests. You should achieve at or near 100% coverage on these classes. We will not unit test the PrimaryWindow
, OrderPanel
, or MenuPanel
classes in this milestone. - Russ
Python users: See the section at the bottom of this milestone for updates to the tox.ini
file to enable full unit testing via tox.
Finally, the following requirements from the previous milestone are continued:
gamegrub.gui
package and sub-packages do require all appropriate documentation comments, and must be free of style errors. Every method must include full documentation comments.gamegrub.gui
base package do not require unit tests, but all entree, drink, and side panels require unit tests as outlined above.gamegrub.gui
package and sub-packages do not require type hints in Python, though you may continue to use them if they are helpful. Any errors from Mypy originating in these classes will be ignored.Completing this project is estimated to require 3-8 hours.
A rough estimate for this milestone would be around 3000-3500 lines of new or updated code. It could vary widely based on how you choose to implement the various portions of the GUI. Most of the new code (around 2000-2500 lines) is contained in the unit tests, which are highly redundant. It took me less than an hour to take a working set of unit tests for one of the more complex panels, and I used that as a template to create the rest of the unit tests. My current model solution contains ~850 unit tests, and I was able to achieve 100% code coverage on all GUI item panels. -Russ
This assignment will be graded based on the rubric below:
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.
As part of the grading of all assignments in this course, I will be doing a deep dive into a few classes in your code. This will include leaving detailed comments on code style and format in GitHub. I will usually choose various classes to review at random, and any issues found in that class will be verified in other classes of the same type. For any GUI portions, I’ll also be testing the functionality of the GUI for each class under review. - Russ
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.
Below are some GUI sketches to help you visualize one possible GUI for this project. You do not have to match this design at all, but this is at least a good starting point that you can reach based on what you know so far.
I found these methods helpful in my solution:
PrimaryWindow.addItem(item)
- basically a pass-through method that calls the OrderPanel.addItem(item)
method. This method would be accessible to all order item panels since they get a reference to the PrimaryWindow
instance.OrderPanel.addItem(item)
- adds a new item to the tree element, or updates the item if it is already contained in the tree.==
operator in Java, or the is
operator in Python. This means that you won’t be able to use the normal contains()
or in
method for determining if the item is already in a list - you must iterate through the list manually.OrderPanel.updateTree(item, node)
- handles actually updating the tree. If node
is null
or not provided, it creates a new one, otherwise it uses the existing node
and updates it. It should return the node
or that node’s id
when complete.Each entree panel test class should contain unit tests for the following:
actionPerformed()
method with an invalid action command, and assert that an exception is not thrown (it should not do anything).Each side panel test class should contain unit tests for the following:
actionPerformed()
method with an invalid action command, and assert that an exception is not thrown (it should not do anything).Each drink panel test class should contain unit tests for the following:
actionPerformed()
method with an invalid action command, and assert that an exception is not thrown (it should not do anything).To allow proper unit testing, you may need to relax the permissions on several elements inside of your GUI classes. I recommend using package-private
in Java, with no modifier - see this document. Then, any unit tests that are in the same package can have access to those members. For Python, switching from double underscore private attributes to single underscore protected attributes is sufficient.
I ran into issues with Python not running unit tests in tox properly on this assignment. There are two causes:
DISPLAY
environment variable.An updated tox.ini
file is given below. I recommend replacing your file with this one:
[tox]
envlist = py39
skipsdist = True
[testenv]
deps = -rrequirements.txt
passenv = DISPLAY
ignore_errors = True
commands = python3 -m mypy -p src --html-report reports/mypy
python3 -m coverage run --parallel-mode --source src -m pytest test/gamegrub/data --html=reports/pytest-data/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/gamegrub/gui/entrees --html=reports/pytest-entrees/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/gamegrub/gui/drinks test/gamegrub/gui/sides --html=reports/pytest-side-drinks/index.html
python3 -m coverage combine
python3 -m coverage html -d reports/coverage
python3 -m flake8 --docstring-convention google --format=html --htmldir=reports/flake
python3 -m pdoc --html --force --output-dir reports/doc .
The major changes:
passenv = DISPLAY
will tell the tox environment which display to use when loading tkinter elements.reports/pytest
folder will no longer be updated.coverage combine
command to combine the coverage data from multiple executions of pytest.This page lists the milestone requirements for Milestone 8 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 Game Grub, offering food of all kinds to celebrate our love of games of all kinds.
The eighth milestone involves creating combo meals and orders from the items selected in the GUI. We’ll use this milestone to explore some software design patterns in our code, as well as learn about using test doubles in our unit tests. With this milestone, most of the work on the core functionality of the GUI will be complete.
This milestone introduces one new feature to the project. Instead of specifying a particular set of classes and structure, it is up to you as the developer to determine how to best implement this feature. Some hints are given in the related example project.
Add updated buttons and panels to the GUI to facilitate creation and customization of combos created as part of the previous milestone. It should have the following features:
Combo
class should handle this as defined in a previous milestone.OrderPanel
class will need to be updated to properly handle combos.
At the bottom of this page is a GUI sketch of one possible way to build a screen for customizing a combo. It is designed to reuse the existing panels for each menu item. We will refer to this class as ComboPanel
in this document. In your implementation, you are encouraged to reuse existing code whenever possible - try to stick to the Don’t Repeat Yourself principle. Some hints for this particular implementation:
PrimaryWindow
class/type as its parent, we can abstract that to a ParentPanel
interface that is implemented by both the PrimaryWindow
class and ComboPanel
. This allows the existing order item panels to use the new ComboPanel
as its parent.ComboPanel
ComboPanel
instead of PrimaryWindow
)PrimaryWindow
to add the item to the order.data
package as desired.PanelFactory
since it could be used from within ComboPanel
, but also will be used to create instances of ComboPanel
. A way to resolve this would be to create a ComboPanelFactory
to handle combos, and adapt the code where PanelFactory
is used to direct combo instances to the new ComboPanelFactory
instead.Your new GUI panel(s) should include some basic unit tests modeled after the tests used for the item panels. Specifically, you should test the following:
Combo
object when it is saved.Combo
object when it is saved.Combo
object.You should use test doubles (stubs, fakes, or mocks) in these unit tests to mimic the other parts of the application, including the order items and associated panels. The goal is to only test the new GUI panel(s) in isolation. This may not be possible in Python due to issues with mocking classes from tkinter
.
This assignment will add one new class to the project
gamegrub.gui.PanelFactory
- a class that implements the Factory Method Pattern to return an instance of a GUI panel for a given entree, side, or drink.
PrimaryWindow
parent) should accept the name of a menu item item as a string, and return a panel that represents a new instance of that item, with the parent
GUI element as its parent. You should be able to directly feed an action command from a button click in the GUI directly to this method and get the appropriate panel. If the name
is not recognized, an exception should be thrown.Item
item, PrimaryWindow
parent) should accept an instance of an Item
and return a panel that represents that item, with the parent
GUI element as its parent. If the item
is not recognized, an exception should be thrown.There will also be several updates to existing classes.
MenuPanel
- update to include the following items:
PanelFactory
class to acquire the appropriate GUI panel based on the action command received from button that was clicked.OrderPanel
- update to include the following items:
PanelFactory
class to acquire the appropriate GUI panel based on the item selected in the tree.Order
instance as well.
OrderPanel
constructor.Order
instance and reset all appropriate GUI elements for a new order. This will delete any existing order.
All new and updated classes in this milestone should contain full documentation comments. Every method should be completely documented!
Some previous tests may need to be updated to match new requirements.
Once this milestone is complete, all classes in the following packages should continue to have unit tests that achieve at or near 100% code coverage:
gamegrub.data.*
gamegrub.gui.drinks.*
gamegrub.gui.entrees.*
gamegrub.gui.sides.*
The only classes that do not meet this requirement are PrimaryWindow
, OrderPanel
, PanelFactory
, and MenuPanel
in the gamegrub.gui
package.
Any new classes created to handle editing combos should include unit tests. Refer to the associated example project for some ideas of how to unit test that class.
Completing this project is estimated to require 3-8 hours.
A rough estimate for this milestone would be around 2000 lines of new or updated code. -Russ
This assignment will be graded based on the rubric below:
PanelFactory
OrderPanel
- 20%MenuPanel
- 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.
As part of the grading of all assignments in this course, I will be doing a deep dive into a few classes in your code. This will include leaving detailed comments on code style and format in GitHub. I will usually choose various classes to review at random, and any issues found in that class will be verified in other classes of the same type. - Russ
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.
This page lists the milestone requirements for Milestone 9 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 Game Grub, offering food of all kinds to celebrate our love of games of all kinds.
The ninth milestone involves finalizing the GUI for creating orders and combos, and handling the steps to check out and pay for an order, including printing a receipt. The purpose is to continue to learn how to use and modify an existing GUI and interface with an external library.
Fewer hints will be given as to the overall structure of your implementation for this milestone. Therefore, you will have to make some decisions about how you feel this milestone should be best achieved and the overall structure of your code!
When in doubt, feel free to contact the course instructor to discuss possible ideas. You may also choose to write small “demo” implementations either in this project or one of the related example projects before committing to a particular solution.
Implement the following features into your existing project.
Implement the functionality for a user to checkout and complete an order. This process will make use of an external library to handle credit cards, cash transactions, and printing a receipt. First, you’ll need to install the register
library into your application:
edu.ksu.cs.cc410.register
package.cc410.register
package.When the user clicks the “Checkout” button in the GUI, they should be presented with the following options:
Clicking “Cancel” will return to the main GUI screen without changing the existing order.
Otherwise, see the descriptions below for the process of paying by credit/debit card or cash.
You may wish to use modal dialogs in various places in this milestone to present responses or error message to the user. See How to Make Dialogs for Java or Dialog Windows for Python.
Read this entire section before attempting to build this part of the application. You may wish to develop the wrapper classes and unit tests discussed in the unit testing section first, then use those wrappers in your eventual GUI panels. The design of the wrappers may inform the overall interaction design in the GUI.
When a user chooses to pay by credit card, the application should call the appropriate method of the CardReader
class in the external library. That method will return one of the CardTransactionResult
enumeration values, which describes the result. If the response is APPROVED
, the transaction is completed and the application may proceed to print the receipt (see the description below). Otherwise, the appropriate error message from the CardTransactionResult
should be displayed to the user, and they may choose to try again.
The CardReader
class will return APPROVED
roughly 40% of the time, and each other result will be returned around 10% of the time each.
When the user chooses to pay by cash, the application should show a window where the user can enter the cash denominations and amounts provided from the customer. One possible GUI sketch for this window is included at the bottom of this page.
The GUI should include a “Cancel” button that can be used at any time to cancel the cash transaction and return back to the main GUI screen without changing the existing order.
The CashDrawer
class in the external library is used to keep track of the available amount of each denomination in the drawer and to balance transactions. Each transaction begins by opening the drawer and providing the expected amount to be deposited. Then, while the drawer is open, cash denominations are added to the drawer from the customer and any change given back is deducted from the drawer. When the drawer is closed, the amount it contains must equal the previous amount plus the expected transaction amount. In addition, the total value in the drawer and the count of each denomination in the drawer may only be accessed when the drawer is closed.
Your project must only instantiate a CashDrawer
instance once, when the project is first launched. It should use that same CashDrawer
instance for all transactions, updating it as needed, until the application is closed.
Cash denominations are listed in the CashDenomination
enum, which includes both the name and value of each denomination.
If the customer has not provided enough money to pay for the transaction, your application should not allow it to be finalized. Your application should also handle making appropriate change from the cash drawer when finalizing a transaction. This includes determining the count of each denomination to be given back to the customer. Some tips for completing this portion of the project:
Thankfully, the monetary system in the United States will always guarantee that change will be made with the fewest possible coins by following the naive algorithm described above. So, that greatly simplifies this process.
In addition, since the cash drawer will only accept deposits, we never have to worry about running out of cash. Simply make sure that the cash received from the customer is added to the drawer before removing the change. If needed, you can exchange the denominations provided from the customer to other denominations as part of your algorithm to make change.
Finally, consider multiplying all values by 100 to work with whole integers instead of floating-point values. There is a great risk of floating-point error when working with cash values in this way.
When the transaction is completed successfully, the application may proceed to print the receipt (see the description below).
Once a transaction has been completed successfully, the system should print a receipt containing the details of the transaction. The ReceiptPrinter
class in the external library is used to print a receipt.
The receipt should include the following information:
The receipt can only be printed one line at a time using the appropriate method in the ReceiptPrinter
class, and each line is limited to no more than 40 characters. You are encouraged to make use of simple formatting, ASCII art, and short indentations to make the receipt more readable. There are methods provided in the ReceiptPrinter
class to start and end a receipt.
The ReceiptPrinter
class will print the receipt to a file named receipt.txt
in the project folder. By default, the ReceiptPrinter
will append new receipts to the end of that file. You may wish to empty this file regularly as part of testing, and should not commit it to GitHub.
All new and updated classes in this milestone should contain full documentation comments. All methods must be fully documented!
Your application should include unit tests to test any functionality provided by your application. Specifically, you should test the following:
You do not have to verify that the external library functions correctly. It already contains a complete set of unit tests. You are encouraged to review the source code of the unit tests contained in the external library for examples of how to test your own code!
Instead, you are highly encouraged to write wrapper classes around the classes in the external library using the adapter pattern and test those wrapper classes that contain your logic.
For example:
CashDrawer
wrapper that accepts a transaction amount and a description of the cash denominations provided by the user, and then computes the correct change and returns a description of the denominations and amounts to be given as change. If the user did not provide enough cash, it could throw an exception or some other error.CashDrawer
wrapper that accepts a description of the cash provided by the user, and a description of the change to be given. The method should compute the updated contents of the drawer using its existing contents, making substitutions when needed to handle situations where not enough of a denomination are present, and then return a description of those changes.
ReceiptPrinter
wrapper that accepts an Order
object and returns a list of strings that represent the receipt to be printed. Verify that the contents of that list fully reflect the Order
given to it.
Review the source code of the CashDrawer
class in the external library to see how it uses a hash map or dictionary to keep track of its contents. This is a good model for describing “cash” amounts made up of several denominations and amounts in these methods.
If done correctly, you should not have to create a test double for any of the classes in the external library. While not an unbreakable rule, it is generally considered a bad practice to mock a type you don’t own, as that can lead to issues if the external library’s API changes in the future. The mock version of the library will continue to function as before, meaning tests will pass that would otherwise fail when executed on the real library.
Completing this project is estimated to require 5 - 10 hours.
A rough estimate for this milestone would be around 1500-2000 lines of new or updated code. -Russ
This assignment will be graded based on the rubric below:
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.
You may wish to review the Spinner (Java) or Spinbox (Python) GUI elements.
This page lists the milestone requirements for Milestone 10 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 Game Grub, offering food of all kinds to celebrate our love of games of all kinds.
The tenth milestone involves moving into the web by creating a data-driven website to display the menu and some other information about the restaurant.
Add a Web Framework to the existing project.
python-dotenv
to use a .flaskenv
file.Java Users - You will need to remove the 'org.junit.jupiter:junit-jupiter-api:5.6.2'
entry from the testImplementation
section of the dependencies. It conflicts with the version provided by Spring.
Python Users - You may ignore any type errors from flask_classful
by adding #type: ignore
after the import line.
gamegrub.web
package.gamegrub.web.MenuController
class to act as the controller. It should include the following routes:
/
- a home page for the application./about
- an about page with the text given at the bottom of the page. You may add additional text and items as desired/menu
- a page that includes the entire menu (all predefined combos, entrees, sides, and drinks).
Menu
class to collect these items.Menu
class as desired to make this work.Create a base layout file including the following:
- Game Grub
Create the following template files to match the routes listed above:
index.html
contains an <h1> tag with the title “Homepage” and the following text in a paragraph (you may add additional text as desired):Welcome to Game Grub! Our motto: play fair, eat well!
about.html
contains an <h1> tag with the title “About Game Grub” and the following text in a paragraph (you may add additional text as desired):Game Grub was developed as part of the CC 410 course at Kansas State University by <your name here>.
menu.html
contains the following content:
menu-item
. It should include:
You can format currency values directly in your templates! See Formatting Currencies in Spring using Thymeleaf for Java or using the familiar Python String.format() function as demonstrated in this StackOverflow comment.
Completing this project is estimated to require 2 - 5 hours.
A rough estimate for this milestone would be around 500 lines of new or updated code, the majority of which is HTML. -Russ
This assignment will be graded based on the rubric below:
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.
As part of the grading of all assignments in this course, I will be doing a deep dive into a few classes in your code. This will include leaving detailed comments on code style and format in GitHub. I will usually choose various classes to review at random, and any issues found in that class will be verified in other classes of the same type. For any GUI and Web portions, I’ll also be testing the functionality of the UI for each class under review. - Russ
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.
Below is a screenshot from a previous model solution for some web design inspiration.
This page lists the milestone requirements for Milestone 11 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 Game Grub, offering food of all kinds to celebrate our love of games of all kinds.
The eleventh milestone involves augmenting the menu display from the previous project by adding search and filtering functionality via an HTML form.
This milestone adds several pieces of functionality to your existing website, mostly based around searching and retrieving menu items.
Your website should implement a simple search functionality via keywords, which allows the user to enter one or more words, separated by spaces, in a text input field, and then any menu items containing any of those keywords anywhere in the name of the item should be displayed on a results page.
You should also handle the case where keyword searches will return a combo if it contains an item that matches the search term. For example, a search for “chess” should not only return that entree, but also any combos that include that item.
Your search page should be accessible via the search
route/URL. If you used a template layout that includes a search box, such as the Bootstrap Sticky Footer with Navbar, you may implement this search functionality using the search box in the default layout. Make sure that you specify the action
of the form to point to the correct URL, since it will be available on all pages. The form should use the HTTP POST
method.
You may choose to use the same template for both the search page and the results, or different templates. Also, don’t forget to add a link to the search
URL in your site’s navigation in the layout template.
Your website should also implement an advanced search and filter feature. This page will allow the user to find menu items based on the following criteria:
Your advanced search page should include HTML form elements for each of the items given above, arranged to make it clear to the user how to use the form. Try to make it as functional as possible based on the user’s intent. For example, if the user doesn’t enter any keywords, assume that they wish to find all menu items. Likewise, if the user inputs a maximum price but not a minimum, you should show all items that are less than the maximum price given. When submitted, the form should use the HTTP POST
method. If any inputs are invalid or cannot be parsed, you should substitute them with reasonable default values.
Your advanced search page should be accessible via the advancedsearch
route/URL. You should add a link to this URL to your site’s navigation.
You must use the same template for both the search form and displaying results. If the search form has been completed and submitted, the submitted values should be present in the form where the results are displayed. Likewise, if the form has not been completed or no results are present, the site should clearly present that information to the user.
The functions required to search and filter the menu should be implemented in the existing Menu
class as static methods. You should not perform any searching in the web application controller itself - it should simply call these methods as needed.
Some recommended functions you may wish to implement:
filterKeywords(Iterable<Item> items, String keywords) - returns Iterable<Item>
filterTypes(Iterable<Item> items, boolean entree, boolean side, boolean drink, boolean combo) - returns Iterable<Item>
filterPrice(Iterable<Item> items, float min, float max) - returns Iterable<Item>
filterCalories(Iterable<Item> items, int min, int max) - returns Iterable<Item>
Each new method added to Menu
should include proper unit tests. You are encouraged to use test doubles (mocks, etc.) to test these methods rather than using actual menu items.
In the method signature above, the Iterable
class is simply an interface. In Java, you can use a List
subtype such as LinkedList
that supports that interface. In Python, the base List
type will also work. - Russ
Menu
class require unit tests to achieve 100% coverage. You should use test doubles in these unit tests, and make sure you are testing all possible outcomes.Completing this project is estimated to require 2 - 5 hours.
A rough estimate for this milestone would be around 750 lines of new or updated code, the majority of which is HTML and unit tests. -Russ
This assignment will be graded based on the rubric below:
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.
As part of the grading of all assignments in this course, I will be doing a deep dive into a few classes in your code. This will include leaving detailed comments on code style and format in GitHub. I will usually choose various classes to review at random, and any issues found in that class will be verified in other classes of the same type. For any GUI and Web portions, I’ll also be testing the functionality of the UI for each class under review. - Russ
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.
This page lists the milestone requirements for Milestone 12 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 Game Grub, offering food of all kinds to celebrate our love of games of all kinds.
The twelfth milestone involves building a RESTful web application that could be used to manage custom menu items.
This milestone adds several pieces of functionality to your existing website, focused on managing custom menu items. First, you’ll need to add new classes to represent and store the custom items. Then, you’ll create a new web controller that follows a RESTful architecture to manage these custom items. While doing so, you’ll also create several templates to display the custom items on the web. Finally, you’ll update the UML diagram for your application to include the new web application classes.
Create a class gamegrub.data.custom.CustomItem
that can represent a custom menu item. It should implement the Item
interface, and should include both getters and setters for all required attributes. The class itself should only store the name, price, and calories of the item. It may simply return an empty list for special instructions. You may add additional utility methods as desired.
The class should include full documentation comments. You do not have to create any unit tests for this class.
Create a class gamegrub.data.custom.CustomItemList
that represents a list of custom menu items. This class should implement both the Iterator design pattern (using the Iterable<CustomItem>
type), as well as the Singleton design pattern. This class is designed to keep a single list of custom items in memory for the entire application. We are using the singleton pattern so that it can be instantiated in the web controllers as needed, and it will always refer to the same list.
This class should maintain a list of CustomItem
objects, and provide methods for adding, retrieving, updating, and deleting those items. You may add additional utility methods as desired.
The class should include full documentation comments. You do not have to create any unit tests for this class.
In Java, you may wish to refer to the methods commonly used in the List interface. In Python, you may wish to refer to the methods in the MutableSequence abstract base class, which includes “dunder” methods __getitem__
, __setitem__
and __delitem__
, among others.
In the next milestone, we will add serialization capabilities to this class, which will allow us to maintain a list of custom items across many application executions.
Create a new web controller named CustomController
to handle these custom items. It should follow a RESTful architectural style. Specifically, it should include the following URL routes:
HTTP Method | URL Path | Description | CRUD Method |
---|---|---|---|
GET | /custom |
Display all custom items. | Read All |
GET | /custom/new |
Display a form to create a new item. | N/A |
POST | /custom |
Create a new custom item | Create |
GET | /custom/{id} |
Display a single custom item | Read One |
GET | /custom/{id}/edit |
Display a form to edit the custom item | N/A |
POST | /custom/{id} |
Update the custom item | Update |
GET | /custom/{id}/delete |
Display a warning page before deleting an item | N/A |
POST | /custom/{id}/delete |
Delete the custom item | Destroy |
More details about each page is included below. In these URLs, assume the {id}
is the index of the custom menu item in the CustomItemList
data structure.
The class should include full documentation comments. You do not have to create any unit tests for this class.
Unlike an actual RESTful application, this application will NOT maintain the same identifier for an item indefinitely. For example, if there are three items in the list, and the second item is removed, the identifier for the third item will now be changed. This is because it is now at a different index in the CustomItemList
data structure, and because of this the URL to access that item will also change. However, since we are not using a relational database to store our data, this is a reasonable compromise that allows us to explore a RESTful architecture without the extra complexity of a database.
Since our application should also be following the HATEOAS model, the links on the index page should be updated as soon as it is reloaded in the browser. So, we’ll still be able to interact with our application, but it will only work well with just a single tab open. Otherwise, any deletions might cause unintended consequences.
Likewise, since browsers only natively support the HTTP GET and POST methods, we won’t be using PUT or DELETE here. Using those methods requires client-side JavaScript code, which is outside of the scope of this class.
Add a link to the /custom
route to the navigation section of your site’s base layout template. This should be clearly accessible via the navigation menu or a similar structure.
You are encouraged to reuse the content from your existing template for displaying all custom menu items here. Each custom menu item should include a link to the /custom/{id}
route for that item.
This is a new page, but it can also reuse content from the existing template for menu items - just remove the loop! This page should include links to the /custom/{id}/edit
and /custom/{id}/delete
routes, as well as a link to the main /custom
route.
You’ll need to create a form that can be used for creating new items or editing existing items. Much of the template code is reused, and there are ways to use the same template for both routes. You may include additional HTML attributes on the HTML form to add limits to the numerical values. However, your web application may assume that data submitted matches the expected format. We will handle validation of form data in the next milestone.
Python users are encouraged to use Flask-WTF to create a special class for representing the form, as demonstrated in the example video. This will make the next milestone much simpler.
Unfortunately, there is not something similar for Java users, but the Spring framework already includes parts that make the next milestone very simple with the existing code, only with slight modifications.
This page is a copy of the single item page, but with additional warnings about deleting the item. This page should have a form that uses the HTTP POST method to submit to the same URL. When submitted, it should delete the item from the list.
For the user, the process to delete an item should follow this pattern:
/custom
- find the item to delete and click the link to see details./custom/{id}
- click the delete link to delete the item./custom/{id}/delete
- see a warning page about deleting, and click the delete link again./custom/{id}/delete
- browser sends a POST request to this URL to delete the item (this is invisible to the user)/custom
- browser is redirected back to the main pageAt the end of this project, you should create a new UML diagram for the project that includes the new web application classes. It should also show the links to other classes/packages in the application, but those items do not require any details (they can just be simple boxes containing the class or package name.)
Completing this project is estimated to require 2 - 5 hours.
A rough estimate for this milestone would be around 500 lines of new or updated code. The new controller and new classes are under 100 lines each. However, the small amount of code required involves some complexity to make everything function properly. There are many moving pieces to this milestone, but they are all pretty simple to put together. Try to reuse existing template resources whenever possible, and get a small portion working before starting on the next. It is simplest to start with creating a new custom item, displaying the entire list, and displaying a single item. From there, most of those parts can be reused to build the rest of the application. -Russ
This assignment will be graded based on the rubric below:
CustomItem
class - 10%CustomItemList
class - 20%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.
As part of the grading of all assignments in this course, I will be doing a deep dive into a few classes in your code. This will include leaving detailed comments on code style and format in GitHub. I will usually choose various classes to review at random, and any issues found in that class will be verified in other classes of the same type. For any GUI and Web portions, I’ll also be testing the functionality of the UI for each class under review. - Russ
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.
This page lists the milestone requirements for Milestone 13 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 Game Grub, offering food of all kinds to celebrate our love of games of all kinds.
The thirteenth milestone involves adding form validation and serialization to the existing project, specifically targeted at custom menu items.
This milestone consists of two portions: adding form validation to the forms for creating and editing custom items, and serializing those custom items to a file.
Update the forms for creating and editing custom menu items to perform server-side validation. This should use the built-in features of either Java Spring or Python Flask, as demonstrated in the example video. The following validation rules should be enforced:
name
of the custom menu item should not be null, and have at least 4 characters.price
of the custom menu item must be greater than or equal to 1.50, and support no more than 2 decimal places. You may either use a validator for this or implement rounding in the setter for this item.calories
of the custom menu item must be an integer greater than or equal to 250.When validation fails, the user should be taken back to the form, where the entered values are still present and the validation errors are clearly displayed.
Java developers will need to change the price
attribute to use the BigDecimal
class (Javadoc) in order to enforce a limit on the number of digits using a validator. I recommend maintaining the existing getter and setters for price
(adapting them to use the value in the new BigDecimal
class) and then adding new getters and setters for this attribute. Likewise, in the HTML form, you’ll use the new BigDecimal
attribute instead of the existing price
. See the example video for details.
Update the application to use serialization to store and load the list of custom items. You may choose any file format (XML, JSON, or binary, or another of your choosing). See the serialization examples on GitHub (Java or Python) as well as the textbook for code you can use.
CustomItemList
class is created. In Java, this would most likely be the getInstance()
method, while in Python it would be in the __new__()
method. So, when the user first visits the /custom
page, the previously saved custom items should appear.CustomItemList
class should implement a new method called save
that will serialize the current contents of the custom item list to a file.CustomController
with the path /custom/save
that will save the existing custom items list to file by calling the new save
method./custom
index page containing a button to save the custom items by sending a POST request to the new route. This form will be very similar to the one used on the page for deleting items.The code should include proper exception handling when reading and writing files, as well as ensuring the file is properly closed. In Java, a try with resources statement is recommended. In Python, a with inside a try structure is recommended. You may simply catch the generic exception and print it to the terminal instead of handling multiple exception types.
As proof of working serialization, create the following custom menu item and serialize it to a file, then ensure that file is committed to your Git repository when committing this project.
Completing this project is estimated to require 2 - 5 hours.
A rough estimate for this milestone would be around 100 lines of new or updated code.-Russ
This assignment will be graded based on the rubric below:
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.
As part of the grading of all assignments in this course, I will be doing a deep dive into a few classes in your code. This will include leaving detailed comments on code style and format in GitHub. I will usually choose various classes to review at random, and any issues found in that class will be verified in other classes of the same type. For any GUI and Web portions, I’ll also be testing the functionality of the UI for each class under review. - Russ
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.