Previous Semesters
Previous Semesters
Previous Semesters
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.
All projects must follow these professional coding standards:
__init__.py and __main__.py are exempt.application, jacoco, and checkstyle plugins.flake8-docstrings and pep8-naming plugins. Code should conform to PEP 8 style with Google style docstrings.A complete final project should include the following features:
As of January 2021, this list is subject to change as the course progresses, depending on how far into the content we get. - Russ
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.
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 70%.
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.
All projects must follow these professional coding standards:
__init__.py and __main__.py are exempt.application, jacoco, and checkstyle plugins.flake8-docstrings and pep8-naming plugins. Code should conform to PEP 8 style with Google style docstrings.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 Starfleet Subs, based in the Star Trek universe.
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.The following requirements ARE NOT enforced for this milestone, but will be enforced in later milestones that use the same code. We will focus on learning to meet each of these requirements in future modules. However, you are welcome to “plan ahead” by minimizing the number of style errors in your code and adding some basic documentation where desired.
You can make things easier on yourself by following proper naming standards for your language of choice, even though we aren’t enforcing a style guide for this milestone.
ClassName, methods and attributes start with lowercase like methodName. See the Google Style Guide.method_name, with the exception of classes, which are named in CamelCase starting with an uppercase letter like ClassName. See the Google Style Guide.It is easier to get this correct from the start, then having to refactor your code later. Of course, major refactoring is also a good lesson that guarantees you’ll get it right in the future!
flake8-docstrings and pep8-naming plugins. Code should conform to PEP 8 style with Google style docstrings.This milestone should include the following features:
starfleetsubs.data.entrees packagestarfleetsubs.data.sides packagestarfleetsubs.data.drinks packagestarfleetsubs.data.enums packageSee the Starfleet Subs 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 entrées like TheRiker and start there. Once you have the entrées 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.
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: to boldly eat a sandwich where no sandwich has been eaten before
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 entrée should be stored in an appropriately named class in the starfleetsubs.data.entrees package. Each entrée should include an attribute for the following data:
Bread value (see below). It should have a getter and setter method.Condiment values (see below).
In addition, each entrée 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.
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 entrée class should also override the default string representation method (toString() in Java or __str__() in Python) and return a string that properly describes the entrée. The string should be formatted as “{sandwich name} on {bread}”, such as “The Kirk on White Bread”.
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 entrée description will include a list of ingredients included on the sandwich. 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 Ham”, to be added to the Special Instructions list. Likewise, changing it back to true will remove the appropriate message. If all ingredients are at their default values, the Special Instructions list should be empty.
Likewise, each entrée description will include a Price, number of Calories, a default value for Bread and a default set of Condiments. Those attributes should be populated appropriately in the constructor for the entrée. Changes to the Bread and Condiments attributes will not affect the Special Instructions attribute. Likewise, the Price and number of Calories will remain constant, regardless of other attributes.
just like the man himself, this sandwich “hams” it up and is super “cheesy”
starfleetsubs.data.entrees.TheKirk - The price is $6.35 and it is 650 calories. Served on White Bread with Ham and Cheese. Comes with Lettuce, Tomato, and Mayo.
a heartier sandwich, with turkey and bacon to keep your ship in top shape
starfleetsubs.data.entrees.TheScotty - The price is $7.65 and it is 800 calories. Served on Wheat Bread with Ham, Turkey, Bacon and Cheese. Comes with Lettuce, Tomato, Onion, Mustard and Mayo.
a sandwich tasty enough for any “voyager” to enjoy
starfleetsubs.data.entrees.TheJaneway - The price is $9.35 and it is 950 calories. Served on White Bread with Ham, Pepperoni, Salami and Cheese. Comes with Lettuce, Tomato, Onion, Pickles, Peppers, and Mayo.
the ultimate judgement of humanity, a “continuum” of meats
starfleetsubs.data.entrees.TheQ - The price is $11.25 and it is 1375 calories. Served on White Bread with Brisket, Pulled Pork, Sausage, and Bacon. Comes with Onion, Pickles, and BBQ Sauce.
a Klingon delicacy to feed a true warrior’s hunger
starfleetsubs.data.entrees.TheGagh - The price is $8.45 and it is 1020 calories. Served on Sourdough Bread with Meatballs, Marinara and Cheese. Comes with no condiments by default.
our “number one” sandwich
starfleetsubs.data.entrees.TheRiker - The price is $17.01 and it is 1701 calories. Served on Wheat Bread with Ham, Turkey, Pepperoni, Salami, Brisket, Pulled Pork, Bacon and Cheese. Comes with Lettuce, Tomato, Onion, Pickles, Peppers, Olives, Mayo, Mustard, and BBQ Sauce
a most logical choice
starfleetsubs.data.entrees.TheSpock - The price is $5.50 and it is 700 calories. Served on Wheat Bread with Cheese. Comes with Lettuce, Tomato, Onion, Pickles, Peppers, Olives, and Mayo.
Each side should be stored in an appropriately named class in the starfleetsubs.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. It should have a getter method.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 “Small Data Chips”.
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 Small. Those attributes should be populated appropriately in the constructor for the side, and should be updated if the Size attribute changes.
crispy, crunchy potato chips seeking to understand human emotions
starfleetsubs.data.sides.DataChips - Small: $1.75 and 250 calories. Medium: $2.25 and 350 calories. Large: $3.50 and 550 calories.
a round cookie and two gherkin “nacelles” in honor of the best ship in the fleet
starfleetsubs.data.sides.Enterprise - Small: $1.98 and 170 calories. Medium: $3.77 and 340 calories. Large: $5.55 and 510 calories.
it is “futile” to “resist” these identical square pretzel bites wrapped in foil
starfleetsubs.data.sides.Borg - Small: $2.55 and 375 calories. Medium: $4.15 and 565 calories. Large: $6.65 and 780 calories.
these wings are the best “bones” in the galaxy
starfleetsubs.data.sides.BonesMcCoy - Small: $3.75 and 545 calories. Medium: $5.45 and 785 calories. Large: $6.75 and 925 calories.
Each drink should be stored in an appropriately named class in the starfleetsubs.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 “Small Picard”.
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 ingredients it includes by default. 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 Whipped Cream”, to be added to the Special Instructions list. Likewise, changing it back to true will remove the appropriate message.
In addition, drinks may include optional ingredients that 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 {ingredient}” message, such as “Add Ice”, to be added to the Special Instructions list. Likewise, changing it back to false will remove the appropriate message. If all ingredients are at their default values, the Special 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 Small. Those attributes should be populated appropriately in the constructor for that class, and should be updated if the Size attribute changes. Changes to the Size attribute will not affect the Special Instructions attribute.
tea, Earl Grey, hot
starfleetsubs.data.drinks.ThePicard - Tea served with Lemon. Can optionally add Ice. Small: $0.95 and 5 calories. Medium: $1.65 and 10 calories. Large: $2.25 and 15 calories.
the ultimate comfort drink inspired by a chocolate sundae
starfleetsubs.data.drinks.TheTroi - Espresso served with Chocolate, Whipped Cream and a Cherry. Can optionally add Extra Espresso Shot. Small: $3.75 and 300 calories. Medium: $4.35 and 425 calories. Large: $5.25 and 600 calories.
a warrior’s drink
starfleetsubs.data.drinks.TheWorf - Prune Juice. Can optionally add Ice. Small: $1.25 and 150 calories. Medium: $1.75 and 225 calories. Large: $2.55 and 415 calories.
a refreshing drink for a mysterious connoisseur
starfleetsubs.data.drinks.TheGuinan - Lemonade served with Ice. Can optionally add Strawberry and/or Cherry. Small: $2.30 and 150 calories. Medium: $3.45 and 225 calories. Large: $4.65 and 395 calories.
the ultimate in hydration, direct from Altair IV
starfleetsubs.data.drinks.AltairWater - Can optionally add Ice and/or Lemon. All sizes are $0.50 and 0 calories.
Each enumeration should be stored in an appropriately named class in the starfleetsubs.data.emnums 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 upper deck and a lower deck is important for any sub
starfleetsubs.data.enums.Bread - White Bread, Wheat Bread, Sourdough Bread
options to fit any appetite
starfleetsubs.data.enums.Size - Small, Medium, Large
don’t forget your KHAAAAAANNNNN!-diments
starfleetsubs.data.enums.Condiment - Lettuce, Tomato, Onion, Pickles, Peppers, Olives, Mayo, Mustard, BBQ Sauce
Special thanks to Nathan, Stephen, Sarah, Kellie, Dan, Jack, Josh, Pascal, Beth, and Vince 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 Starfleet Subs, based in the Star Trek universe.
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.The following requirements ARE NOT enforced for this milestone, but will be enforced in later milestones that use the same code. We will focus on learning to meet each of these requirements in future modules. However, you are welcome to “plan ahead” by minimizing the number of style errors in your code and adding some basic documentation where desired.
You can make things easier on yourself by following proper naming standards for your language of choice, even though we aren’t enforcing a style guide for this milestone.
ClassName, methods and attributes start with lowercase like methodName. See the Google Style Guide.method_name, with the exception of classes, which are named in CamelCase starting with an uppercase letter like ClassName. See the Google Style Guide.It is easier to get this correct from the start, then having to refactor your code later. Of course, major refactoring is also a good lesson that guarantees you’ll get it right in the future!
flake8-docstrings and pep8-naming plugins. Code should conform to PEP 8 style with Google style docstrings.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 entrée 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.ham or lemon) 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("bread", Bread).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 entrées like TheRiker and start there writing unit tests. Once you have the entrées all working, the sides and drinks are pretty easy and use much of the same structure. There are 423 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.
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 entrée test class should contain unit tests for the following:
SpecialInstructionsInitiallyEmpty() - the SpecialInstructions list should be empty when the object is createdHasCorrectBreadInitially() - the Bread attribute is initially set correctlyHasCorrectPrice() - the price is correctHasCorrectCalories() - the calories is correctNameIsCorrectForBread(Bread) - call the toString() or __str__() method with each type of bread and verify the output.IncludesCorrectCondimentsByDefault(Condiment) - for each condiment, check if it is included or not by default.
boolean value indicating if the condiment should be included by default.AddRemoveCondiments(Condiment) - for each condiment, check that it can be added and removed, and the Condiments set will change accordingly.Has<Ingredient>ByDefault() - for each ingredient, check to see that it is included by default (returns true).
TheKirk would have a test method HasHamByDefault().Change<Ingredient>SetsSpecialInstructions() - for each ingredient, check that changing it from and to the default value will add and remove the correct item from the SpecialInstructions list.
TheKirk would have ChangeHamSetsSpecialInstructions() that would confirm setting ham to false would add "Hold Ham" to the list of SpecialInstructions.ChangeMultipleIngredientSpecialInstructions() - confirm that changing multiple ingredients from their default values will add multiple items to the SpecialInstructions list.
SameObjectsAreEqual() - generate two different instances of the item, and confirm that they are equal using equals() (Java) or == (Python).DifferentBreadNotEqual() - generate two different instances of the item using different bread, and confirm that they are not equal using equals() (Java) or == (Python).DifferentIngredientsNotEqual() - generate two different instances of the item using different sets of ingredients, and confirm that they are not equal using equals() (Java) or == (Python).DifferentCondimentsNotEqual() - generate two different instances of the item using different sets of condiments, and confirm that they are not equal using equals() (Java) or == (Python).WrongObjectNotEqual() - generate an instance of the item and an instance of a different menu item, and confirm that they are not equal using equals() (Java) or -- (Python). This should not throw an exception.Each side test class should contain unit tests for the following:
DefaultSizeCorrect() - each side should have the default size of Small when initially created.HasCorrectNameForSize(Size) - call the toString() or __str__() method with each size and verify the output.HasCorrectPriceForSize(Size) - the price is correct for each sizeHasCorrectCaloriesForSize(Size) - the calories is correct for each sizeSameObjectsAreEqual() - generate two different instances of the item, and confirm that they are equal using equals() (Java) or == (Python).DifferentSizeNotEqual() - generate two different instances of the item using different sizes, and confirm that they are not equal using equals() (Java) or == (Python).WrongObjectNotEqual() - generate an instance of the item and an instance of a different menu item, and confirm that they are not equal using equals() (Java) or -- (Python). This should not throw an exception.Each drink test class should contain unit tests for the following:
SpecialInstructionsInitiallyEmpty() - the SpecialInstructions list should be empty when the object is createdDefaultSizeCorrect() - each drink should have the default size of Small when initially created.HasCorrectNameForSize(Size) - call the toString() or __str__() method with each size and verify the output.HasCorrectPriceForSize(Size) - the price is correct for each sizeHasCorrectCaloriesForSize(Size) - the calories is correct for each sizeHas<Ingredient>ByDefault() - for each ingredient included by default, check to see that it is included (returns true). For example, ThePicard would have a test method HasLemonByDefault().DoesNotHave<Ingredient>ByDefault() - for each optional ingredient not included by default, check to see that it is not included (returns false).
ThePicard would have a test method DoesNotHaveIceByDefault().Change<Ingredient>SetsSpecialInstructions() - for each ingredient, check that changing it from and to the default value will add and remove the correct item from the SpecialInstructions list.
ThePicard would have ChangeIceSetsSpecialInstructions() that would confirm setting ice to true would add "Add Ice" to the list of SpecialInstructions.ChangeMultipleIngredientSpecialInstructions() - confirm that changing multiple ingredients from their default values will add multiple items to the SpecialInstructions list.
SameObjectsAreEqual() - generate two different instances of the item, and confirm that they are equal using equals() (Java) or == (Python).DifferentSizeNotEqual() - generate two different instances of the item using different sizes, and confirm that they are not equal using equals() (Java) or == (Python).DifferentIngredientsNotEqual() - generate two different instances of the item using different sets of ingredients, and confirm that they are not equal using equals() (Java) or == (Python).WrongObjectNotEqual() - generate an instance of the item and an instance of a different menu item, and confirm that they are not equal using equals() (Java) or -- (Python). This should not throw an exception.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 Starfleet Subs, based in the Star Trek universe.
The third milestone involves refactoring our code to take advantage of inheritance and the use of interfaces. We’ll also need to update our documentation and unit tests accordingly.
This project is the first that requires ALL general requirements introduced in the “Hello Real World” project. Read this section carefully to see what is required for this particular milestone.
This milestone must follow these professional coding standards:
__init__.py and __main__.py are exempt.application plugin. The project should compile without errors. You may include a main class in a separate package for testing purposes only.flake8-docstrings and pep8-naming plugins. Code should conform to PEP 8 style with Google style docstrings.This milestone should include the following features:
starfleetsubs.data.menu.OrderItem interface that is implemented by all entrée, side, and drink classes
starfleetsubs.data.entrees.Entree base classstarfleetsubs.data.sides.Side base classstarfleetsubs.data.drinks.Drink base classstarfleetsubs.data.menu.Menu that contains the full menu
Menu class should containOrderItem interfaceMenu and OrderItem should report near 100% code coverage.Menu to confirm that each possible menu item is present in the menu.Completing this project is estimated to require 3-8 hours.
A rough estimate for this milestone would be around 1000 lines of new or updated code, and around 500 lines of redundant code removed. It could vary widely based on how you choose to implement the inheritance between the base classes and the interface. My model solution for this milestone now contains 526 unit tests in total. -Russ
This assignment will be graded based on the rubric below:
OrderItem Interface - 25%Entree Base Class - 10%Side Base Class - 10%Drink Base Class - 10%Menu Class - 20%Menu Unit Tests - 10%The following deductions apply:
This is not an exhaustive list of possible deductions. The instructors will strive to provide reasonable and fair grading, but we can’t predict all possible defects. It is up to the student to ensure that the project is complete and correct before submission.
Submit this assignment by creating a release on GitHub and uploading the release URL to the assignment on Canvas. You should not submit this Codio project or mark it as complete in Codio, in case you need to come back to it and make changes later.
The starfleetsubs.data.menu.OrderItem class should be created as an interface that can be implemented by all other menu items. It should contain the following elements as abstract methods/properties:
Each menu item (entrées, sides, and drinks) should be refactored to implement this interface. This will require some changes:
Entree base class.Side base class.Accordingly, the unit tests for some of these classes will need updated, as discussed below.
Each of the three types of menu items should directly inherit from a new abstract base class. These classes should not be instantiated!
starfleetsubs.data.entrees.Entree is the base class for all entrée items. It should include the following elements that are common to all entrée classes:
starfleetsubs.data.sides.Side is the base class for all side items. It should include the following elements that are common to all side classes:
starfleetsubs.data.drinks.Drink is the base class for all drink items. It should include the following elements that are common to all drink classes:
You may choose to implement the OrderItem interface on the three base classes described below, which will then be inherited by each menu item, instead of explicitly implementing the interface on each menu item itself. Some of the elements described on these base classes are already defined in the OrderItem interface, so if you implement the interface at the base class level you do not need to redefine the abstract methods from the interface within the abstract base classes. Either approach is valid!
If you choose to inherit from the OrderItem interface in the base classes in Python, the base class should not inherit from ABC - that is already covered as part of the interface. If you do, Mypy will present an error stating that it “cannot determine consistent method resolution order.”
You may also need to refactor some private attributes (with double underscores in Python) to protected attributes (single underscores in Python) as they move from the subclass to the superclass. In Java, these are just attributes as expected. In Python, it is simplest to declare those in the constructor of the superclass (such as self._size = Size.SMALL), then make sure you call that constructor using super().__init__() in the subclass’ constructor.
The starfleetsubs.data.menu.Menu class should be a class that has static getter methods for these four elements:
entrees - a list of OrderItem elements containing an instance of all available entrées (7 in total).sides - a list of OrderItem elements containing an instance of all available sides. Since each side is available in three sizes, the list should include an instance of all three sizes of each side item (12 in total).drinks - a list of OrderItem elements containing an instance of all available drinks. Since each drink is available in three sizes, the list should include an instance of all three sizes of each drink item (15 in total).fullmenu - a combined list of all menu items (34 in total).In Java, these lists should use a subclass of the List interface. In Python, these methods should use the built-in Python list data type. Since they are static methods, they cannot be constructed as Python properties using the @property decorator.
The following updates must be made to the existing unit tests in this project to accommodate these code changes:
Add:
InheritsFromEntree() - check if a given object inherits from the base Entree class.ImplementsOrderItem() - check if a given object implements the interface OrderItem.ChangeCondimentSetsSpecialInstructions(Condiment) - for each condiment, check that changing it from and to the default value will add and remove the correct item from the SpecialInstructions list.Update:
SpecialInstructionsInitiallyEmpty() should be renamed SpecialInstructionsInitiallyCondiments() and should now verify that the initial set of condiments is in the special instructions list.Add:
InheritsFromSide() - check if a given object inherits from the base Side class.ImplementsOrderItem() - check if a given object implements the interface OrderItem.SpecialInstructionsEmpty() - check that the Special Instructions list is always empty.Add:
InheritsFromDrink() - check if a given object inherits from the base Drink class.ImplementsOrderItem() - check if a given object implements the interface OrderItem.To check for type compatibility, use the object instanceof Class operator in Java, or the isinstance(object, Class) method in Python as part of an assertion statement. Hamcrest also includes a few matchers for this, such as isA (Java) or instance_of() (Python).
Create a new test class for the Menu static class:
IncludesAllEntrees() - test that the entrees list contains an instance of each entrée classIncludesAllSides() - test that the sides list contains an instance of each side class for each sizeIncludesAllDrinks() - test that the drinks list contains an instance of each drink class for each sizeIncludesAllItems() - test that the fullmenu list contains an instance of every menu item.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 Starfleet Subs, based in the Star Trek universe.
The fourth 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 must follow these professional coding standards:
__init__.py and __main__.py are exempt.application plugin. The project should compile without errors.starfleetsubs.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.flake8-docstrings and pep8-naming plugins. Code should conform to PEP 8 style with Google style docstrings.This milestone should include the following features:
starfleetsubs.Main class that properly loads and displays the program’s GUI.starfleetsubs.gui.MainWindow class that represents the main GUI window.
starfleetsubs.gui.OrderPanel class to represent the main order screen panel.
starfleetsubs.gui.SidebarPanel class to represent the sidebar panel.
starfleetsubs.gui.entrees package for each entrée item.
EntreePanel class to reduce the amount of duplicate code.SidePanel in the starfleetsubs.gui.sides package.
Side class. However, when buttons on the OrderPanel are clicked, you’ll need to make sure an instance of the correct item is generated.starfleetsubs.gui.drinks package for each drink item.
DrinkPanel class to reduce the amount of duplicate code.starfleetsubs.gui package do not require unit tests.starfleetsubs.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.starfleetsubs.gui package do require all appropriate documentation comments, and must be free of style errors.You are welcome to add additional methods to the existing content in the starfleetsubs.data package. If so, make sure you include appropriate 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%MainWindow class - 4%SidebarPanel class - 4%OrderPanel 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.
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 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 entrée 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 entrée 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 settingsThen, 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 OrderPanel 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 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 Starfleet Subs, based in the Star Trek universe.
The fifth milestone involves dealing with the various events generated by the GUI and constructing a list of items that represent an order.
This milestone must follow these professional coding standards:
__init__.py and __main__.py are exempt.application plugin. The project should compile without errors.starfleetsubs.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.flake8-docstrings and pep8-naming plugins. Code should conform to PEP 8 style with Google style docstrings.This milestone should include the following new GUI features:
SidebarPanel panel.SidebarPanel 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.
SidebarPanel, the following should happen:
It may be helpful to maintain a hash map or dictionary in the SidebarPanel class that associates nodes in the GUI tree element with the actual OrderItem instances that they represent.
In addition, the following events should be implemented in the GUI:
SidebarPanel if it is a new item, or the item should be updated if it is being edited.MainWindow should be replaced with the OrderScreen (this was part of the previous milestone).MainWindow should be replaced with the OrderScreen (this was part of the previous milestone).SidebarPanel is clicked, the following should happen:
OrderItem that is currently selected should be determined. If the selection is an ingredient of that item, the code should work upwards in the tree to find the OrderItem.MainWindow and populated with the current status of the item (most of this should work from the previous milestone).SidebarPanel is clicked, the following should happen:
OrderItem that is currently selected should be determined. If the selection is an ingredient of that item, the code should work upwards in the tree to find the OrderItem.SidebarPanel class.Unit tests should be added to the corresponding test package for the following classes:
starfleetsubs.gui.entreesstarfleetsubs.gui.drinksstarfleetsubs.gui.sides.SidePanelSee 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 MainWindow, OrderPanel, or SidebarPanel classes in this milestone.
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:
starfleetsubs.gui base package do not require unit tests, but all entrée, drink, and side panels require unit tests as outlined above.starfleetsubs.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.starfleetsubs.gui package and sub-packages do require all appropriate documentation comments, and must be free of style errors.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 TheRikerPanel and use that as a template to create the rest of the unit tests. My current model solution contains 849 unit tests, and I was able to achieve 100% code coverage on all GUI OrderItem 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.
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:
MainWindow.addItem(item) - basically a pass-through method that calls the SidebarPanel.addItem(item) method. This method would be accessible to all order item panels since they get a reference to the MainWindow instance.SidebarPanel.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 directly.SidebarPanel.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 entrée panel test class should contain unit tests for the following:
testDefaultConstructor() - create the panel without providing an existing element, and assert that it creates a new instance of the correct item.testBadActionCommand() - call the actionPerformed() method with a bad action command, and assert that an exception is not thrown.testBreadComboBox(Bread) - instantiate a panel with an existing item, change the value of the bread combo box in the GUI to the bread value, and fire a “save” action, then verify that the item has the correct bread value.testBreadComboBoxSetCorrectly(Bread) - instantiate a panel with an existing item using the given bread, and assert that the bread combo box is set to the correct value.test<Ingredient>CheckBox() - instantiate a panel with an existing item, change the value of the ingredient check box in the GUI to a value, and fire a “save” action, then verify that the item has the correct value. Do this for both true and false.test<Ingredient>CheckBoxSetCorrectly() - instantiate a panel with an existing item with a given value for ingredient, and assert that the ingredient checkbox is set to the correct value. Do this for both true and false.testCondimentCheckBox(Condiment) - instantiate a panel with an existing item, change the value of the condiment check box in the GUI to a value, and fire a “save” action, then verify that the item has the correct value. Do this for both true and false.testCondimentCheckBoxSetCorrectly(Condiment) - instantiate a panel with an existing item with a given value for condiment, and assert that the condiment checkbox is set to the correct value. Do this for both true and false.testCancelButton() - instantiate a panel with an existing item, change several values in the GUI, and fire a “cancel” action, then assert that the item is unchanged from its previous state.Each side panel test class should contain unit tests for the following:
testDefaultConstructor<Side>() - create the panel by providing an instance of each side class, and test that its item is set to an instance of that class.testBadActionCommand() - call the actionPerformed() method with a bad action command, and assert that an exception is not thrown.testSizeComboBox(Size) - instantiate a panel with an existing item, change the value of the size combo box in the GUI to the size value, and fire a “save” action, then verify that the item has the correct size value.testSizeComboBoxSetCorrectly(Size) - instantiate a panel with an existing item using the given size, and assert that the size combo box is set to the correct value.testCancelButton() - instantiate a panel with an existing item, change several values in the GUI, and fire a “cancel” action, then assert that the item is unchanged from its previous state.testConstructorEmptyItem() - create the panel by passing a null item, and verify that an exception is thrown.Each drink panel test class should contain unit tests for the following:
testDefaultConstructor() - create the panel without providing an existing element, and assert that it creates a new instance of the correct item.testBadActionCommand() - call the actionPerformed() method with a bad action command, and assert that an exception is not thrown.testSizeComboBox(Size) - instantiate a panel with an existing item, change the value of the size combo box in the GUI to the size value, and fire a “save” action, then verify that the item has the correct size value.testSizeComboBoxSetCorrectly(Size) - instantiate a panel with an existing item using the given size, and assert that the size combo box is set to the correct value.test<Ingredient>CheckBox() - instantiate a panel with an existing item, change the value of the ingredient check box in the GUI to a value, and fire a “save” action, then verify that the item has the correct value. Do this for both true and false.test<Ingredient>CheckBoxSetCorrectly() - instantiate a panel with an existing item with a given value for ingredient, and assert that the ingredient checkbox is set to the correct value. Do this for both true and false.testCancelButton() - instantiate a panel with an existing item, change several values in the GUI, and fire a “cancel” action, then assert that the item is unchanged from its previous state.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/starfleetsubs/data --html=reports/pytest-data/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/starfleetsubs/gui/entrees --html=reports/pytest-entrees/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/starfleetsubs/gui/drinks test/starfleetsubs/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 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 Starfleet Subs, based in the Star Trek universe.
The sixth 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 must follow these professional coding standards:
__init__.py and __main__.py are exempt.application plugin. The project should compile without errors.starfleetsubs.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.flake8-docstrings and pep8-naming plugins. Code should conform to PEP 8 style with Google style docstrings.starfleetsubs.data.menu.Order - this class should represent a collection of OrderItem objects that make up an order.
size() in Java or __len__() in Python).OrderItem object is contained in the collection (contains(item) in Java or __contains__(item) in Python). Recall that this should use the identity test, not the equality test.get(i) method in Java or __getitem__(i) in Python).items of OrderItems, with methods to add and remove items, as well as the iterator pattern methods discussed above.
orderNumber for this order. It will be generated using the OrderNumberSingleton class discussed below. It should only include a getter.taxRate, which is set to 0.12 (12%) by default. It should include static methods to get and set the tax rate, which will be used by all Order objects. The tax rate must be a valid percentage value ranging from 0.0 to 1.0, inclusive.subtotal - the total sum of the prices for each item in the order.tax - the subtotal multiplied by the taxRatetotal - the subtotal plus the tax.calories - the total number of calories in the order.starfleetsubs.data.menu.Combo - this class should implement the OrderItem interface, and represent a combo meal consisting of an entrée, side, and drink.
name - the name of the combo, which does not require a getter (you may add one) or setter. This attribute can be set to null or None.Entree named entree - the entrée in the combo, which does not require a getter (you may add one) or setter. This attribute can be set to null or None. It should include a removeEntree() method to set the value to null or None.Side named side - the side in the combo, which does not require a getter (you may add one) or setter. This attribute can be set to null or None. It should include a removeSide() method to set the value to null or None.Drink named drink - the drink in the combo, which does not require a getter (you may add one) or setter. This attribute can be set to null or None. It should include a removeDrink() method to set the value to null or None.discount - it has a value 0.5 ($0.50) by default. It should include static methods to get and set the discount, which will be used by all Combo objects.OrderItem interface:
price that returns the sum of the prices of each item. If all three items in the combo are populated, the discount is applied to this total. Otherwise, no discount is applied.calories that returns the sum of the calories of each item.specialInstructions that returns the name of the combo, if set, followed by the line "$0.50 Discount Applied" if all three items are populated. It should not include any other items. (The discount value should be updated to match the static discount attribute.)name. The constructor should allow the name to be omitted or set to 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. The constructor should set the entree, side and drink attributes to null or None initially.addItem() method that accepts an OrderItem object and places it in the appropriate attribute (entree, side or drink). It should replace the existing item in that attribute, if any. If the OrderItem is not one of the three types listed above, it should throw an appropriate exception.getItems() method that returns list of the items included in the combo, if any. If none are included, then return an empty list.equals() or __eq__() method to check for equality. Two combos are considered equal if their entree, side, drink, and name are equal (they do not have to be the same instances, just equal). If any attribute in this object is 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.starfleetsubs.data.menu.ComboBuilder - a class that implements the Builder Pattern to build the available combos described below.
buildCombo() that accepts an integer as input, and builds and returns the Combo object indicated by the integer.starfleetsubs.data.menu.OrderNumberSingleton - a class that implements the Singleton Pattern to generate new order numbers.
nextOrderNumber attribute, which is initially set to 1getNextOrderNumber() that will return the next order number.
getInstance() method to get the actual singleton instance stored as a static attribute in the class.nextOrderNumber attribute through that singleton instance.nextOrderNumber attribute (a synchronized statement in Java or a lock in a with statement in Python).starfleetsubs.gui.PanelFactory - a class that implements the Factory Method Pattern to return an instance of a GUI panel for a given entrée, side, or drink.
getPanel(String name, MainWindow 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.getPanel(OrderItem item, MainWindow parent) should accept an instance of an OrderItem 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.Combos as OrderItems. We’ll address that in the next milestone.Menu - update to include the following items:
getCombos() method that returns all pre-configured combos described below. This method should use the ComboBuilder class discussed below.getFullMenu() method to include the combos returned from getCombos() in its output.OrderPanel - update to include the following items:
actionPerformed method should be updated to use the PanelFactory class to acquire the appropriate GUI panel based on the action command received from button that was clicked.SidebarPanel - update to include the following items:
PanelFactory class to acquire the appropriate GUI panel based on the item selected in the tree.Order attribute that stores the items in the order.
SidebarPanel constructor.Order instance and reset all appropriate GUI elements for a new order. This will delete any existing order.
All new classes except PanelFactory should include full unit tests that achieve at or near 100% code coverage and adequately test all aspects of the class. In addition, some previous tests may need to be updated to match new requirements.
Java Only: You should also update the unit tests for each of the GUI panels created in the previous milestone to use a fake MainWindow object instead of creating one in the test. This should make the tests run much faster, and you should be able to see that the code in MainWindow is not executing in the code coverage report.
Python Only: Sadly, I have yet to figure out if it is possible to properly fake parts of tkinter such that the MainWindow class can be properly substituted with a fake. No changes are required at this time.
Once this milestone is complete, all classes in the following packages should have unit tests that achieve at or near 100% code coverage:
starfleetsubs.data.*starfleetsubs.gui.drinks.*starfleetsubs.gui.entrees.*starfleetsubs.gui.sides.*The only classes that do not meet this requirement are MainWindow, OrderPanel, PanelFactory, and SidebarPanel in the starfleetsubs.gui package.
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 - 10%Combo - 10%ComboBuilder - 10%OrderNumberSingleton - 5%PanelFactory - 5%Order - 15%Combo - 15%ComboBuilder - 5%OrderNumberSingleton - 5%Menu and unit tests: 5%OrderPanel: 5%SidebarPanel: 10%The following deductions apply:
This is not an exhaustive list of possible deductions. The instructors will strive to provide reasonable and fair grading, but we can’t predict all possible defects. It is up to the student to ensure that the project is complete and correct before submission.
Submit this assignment by creating a release on GitHub and uploading the release URL to the assignment on Canvas. You should not submit this Codio project or mark it as complete in Codio, in case you need to come back to it and make changes later.
The Kirk, Bones McCoy, Altair Water
The Riker, Data Chips, The Picard
The Janeway, Enterprise, The Guinan
The Gagh, Borg, The Worf
The Scotty, Enterprise, The Troi
The Q, Borg, The Picard
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.
SizeIs0Initially() - the size of the order is initially 0.TotalsAre0Initially() - the subtotal, tax, and total are 0 initially.NegativeTaxRateThrowsException() - setting the tax rate to a negative value throws an exception.TaxRateOver100ThrowsException() - setting the tax rate to a value over 1.0 throws an exception.AddItemsUpdatesSize() - add three fake items one at a time and check size after each one.AddItemsUpdatesTotals() - add three fake items one at a time and check subtotal, tax, and total after each one.AddItemsUpdatesCalories() - add three fake items one at a time and check calories after each one.ContainsUsesInstanceComparison() - confirm that the contains method uses instance comparison. Create two actual order items (this cannot be done with fakes) that will return true when 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.RemoveUsesInstanceComparison() - confirm that the removeItem method uses instance comparison. Create two actual order items (this cannot be done with fakes) that will return true when equals() is called. Place both in in the order, then remove one and confirm that the correct one was removed using contains. You may wish to do this twice, removing the first one added once and the second one added the second time.OrderNumberFromSingleton()- confirm that the Order class is using OrderNumberSingleton. Create a fake OrderNumberSingleton that returns a value for an order number, then instantiate an Order and verify that it received the given order number.TaxRateSetGlobally() - create two 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.RemoveMissingItemDoesNotThrow() - removing an item not in the order should not throw an exception.IteratorContainsItems() - add fake items to the order, get the iterator, and confirm that the fake items are returned in order.GetItemsByIndex() - add fake items to the order, and confirm that each one can be accessed via its index.ConstructorSetsName() - the constructor should set the name. This is visible as the first element in the special instructions list.ConstructorAcceptsNullName() - the constructor should accept null or None for the name.ConstructorSetsItemsToNull() - the constructor should set the entree, side, and drink elements to null or None.SetDiscountToNegativeThrowsException() - setting the discount to a negative value throws an exception.CanSetDiscountToZero() - setting the discount to 0 does not throw an exception.PriceZeroNoItems() - the price should be 0 if all items are null or None.CaloriesZeroNoItems() - the calories should be 0 if all items are null or None.PriceAllItems() - add fake entree, side, and drink to combo and verify that the price is summed correctly (remember to take off the discount).CaloriesAllItems() - add fake entree, side, and drink to combo and verify that the calories is summed correctly.NoDiscountWhenItemMissing() - add two of the three items to the combo and verify that the price is correct and does not include discount.DiscountSetGlobally() - create two Combo instances, change the discount, and confirm that both use the new discount. This is best done by adding three items to each combo and checking the total price.AddEntreeUpdatesEntree() - add an Entree to the combo using addItem() and verify that it is placed in the entree attribute. You may need to make the attribute visible to the test.AddSideUpdatesSide() - add a Side to the combo using addItem() and verify that it is placed in the side attribute. You may need to make the attribute visible to the test.AddDrinkUpdatesDrink() - add a Drink to the combo using addItem() and verify that it is placed in the drink attribute. You may need to make the attribute visible to the test.ItemsListCorrect() - add fake items to the combo and verify that the list returned by getItems() contains them.ItemsListEmpty() - getting a list when the combo is empty results in an empty list.SpecialInstructionsHasDiscount() - special instructions should contain “$0.50 Discount Applied” if all three items are populated.AddingComboToComboThrowsException() - adding a combo as an item to a combo throws an exception.TwoCombosEqual() - create two combos containing the same name and fake objects and test that they are equal.TwoCombosNotEqual() - create two combos with different names but the same fake objects, and test that they are not equal.TwoEmptyCombosEqual() - create two empty combos with null or None names and test that they are equal.TwoCombosOneEmptyNotEqual() - create two combos, one empty, one not, and test that they are not equal.DifferentObjectNotEqual() - confirm that equality test will return false when given a different type of object.You may need to add additional tests of the equals() method in Java to achieve 100% code coverage.
For these tests, I recommend just checking the types of the entree, side, and drink item in the Combo returned, as well as the name, rather than using any fake objects. As before, you may wish to make these attributes visible to the test.
Combo1() - Combo 1 is built correctlyCombo2() - Combo 2 is built correctlyCombo3() - Combo 3 is built correctlyCombo4() - Combo 4 is built correctlyCombo5() - Combo 5 is built correctlyCombo6() - Combo 6 is built correctlyBadComboThrowsException() - a bad combo number should throw an exceptionSequentialOrderNumbers - call getNextOrderNumber() several times and make sure each one is sequential.I ran into even more issues with Python not running unit tests in tox properly on this assignment. As before, it seems to be the same cause:
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/starfleetsubs/data --html=reports/pytest-data/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/starfleetsubs/gui/entrees/test_TheGaghPanel.py --html=reports/pytest-entrees1/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/starfleetsubs/gui/entrees/test_TheJanewayPanel.py --html=reports/pytest-entrees2/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/starfleetsubs/gui/entrees/test_TheKirkPanel.py --html=reports/pytest-entrees3/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/starfleetsubs/gui/entrees/test_TheQPanel.py --html=reports/pytest-entrees4/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/starfleetsubs/gui/entrees/test_TheRikerPanel.py --html=reports/pytest-entrees5/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/starfleetsubs/gui/entrees/test_TheScottyPanel.py --html=reports/pytest-entrees6/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/starfleetsubs/gui/entrees/test_TheSpockPanel.py --html=reports/pytest-entrees7/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/starfleetsubs/gui/drinks test/starfleetsubs/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:
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 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 Starfleet Subs, based in the Star Trek universe.
The seventh milestone involves finalizing the GUI for creating 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.
This milestone must follow these professional coding standards:
__init__.py and __main__.py are exempt.application plugin. The project should compile without errors.starfleetsubs.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.flake8-docstrings and pep8-naming plugins. Code should conform to PEP 8 style with Google style docstrings.It is best to think of this assignment as one consisting of two distinct parts.
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 the previous milestone.SidebarPanel 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:
MainWindow class/type as its parent, we can abstract that to a ParentPanel interface that is implemented by both the MainWindow class and ComboPanel. This allows the existing order item panels to use the new ComboPanel as its parent.ComboPanelComboPanel instead of MainWindow)MainWindow 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.
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 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 now 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 indentions 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.
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 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 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 Starfleet Subs, based in the Star Trek universe.
The eighth milestone involves moving into the web by creating a data-driven website to display the menu and some other information about the restaurant.
This milestone must follow these professional coding standards:
__init__.py and __main__.py are exempt.application plugin. The project should compile without errors.starfleetsubs.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.flake8-docstrings and pep8-naming plugins. Code should conform to PEP 8 style with Google style docstrings.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.
starfleetsubs.web package.starfleetsubs.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./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.Create a base layout file including the following:
- Starfleet SubsCreate the following template files to match the routes listed above:
index.html contains an <h1> tag with the title “Starfleet Subs” and the following text in a paragraph (you may add additional text as desired):Welcome to Starfleet Subs! Our motto: to boldly eat a sandwich where no sandwich has been eaten before!
about.html contains an <h1> tag with the title “About Starfleet Subs” and the following text in a paragraph (you may add additional text as desired):Starfleet Subs 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.
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 the model solution for some web design inspiration.
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 Starfleet Subs, based in the Star Trek universe.
The ninth milestone involves augmenting the menu display from the previous project by adding search and filtering functionality via an HTML form.
This milestone must follow these professional coding standards:
__init__.py and __main__.py are exempt.application plugin. The project should compile without errors.starfleetsubs.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.flake8-docstrings and pep8-naming plugins. Code should conform to PEP 8 style with Google style docstrings.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.
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<OrderItem> items, String keywords) - returns Iterable<OrderItem>filterTypes(Iterable<OrderItem> items, boolean entree, boolean side, boolean drink, boolean combo) - returns Iterable<OrderItem>
filterPrice(Iterable<OrderItem> items, float min, float max) - returns Iterable<OrderItem>filterCalories(Iterable<OrderItem> items, int min, int max) - returns Iterable<OrderItem>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.
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.
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 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 Starfleet Subs, based in the Star Trek universe.
The tenth milestone involves building a RESTful web application that could be used to manage custom menu items.
This milestone must follow these professional coding standards:
__init__.py and __main__.py are exempt.application plugin. The project should compile without errors.starfleetsubs.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.flake8-docstrings and pep8-naming plugins. Code should conform to PEP 8 style with Google style docstrings.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 starfleetsubs.data.menu.CustomItem that can represent a custom menu item. It should implement the OrderItem 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. You do not have to create any unit tests for this class.
Create a class starfleetsubs.data.menu.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. 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 CustomItemController 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 | /customitems |
Display all custom items. | Read All |
| GET | /customitems/new |
Display a form to create a new item. | N/A |
| POST | /customitems |
Create a new custom item | Create |
| GET | /customitems/{id} |
Display a single custom item | Read One |
| GET | /customitems/{id}/edit |
Display a form to edit the custom item | N/A |
| POST | /customitems/{id} |
Update the custom item | Update |
| GET | /customitems/{id}/delete |
Display a warning page before deleting an item | N/A |
| POST | /customitems/{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.
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 /customitems route to the navigation section of your site’s base layout template.
You are encouraged to reuse the content from your existing template for displaying all menu items here. Each menu item should include a link to the /customitems/{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 /customitems/{id}/edit and /customitems/{id}/delete routes, as well as a link to the main /customitems 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:
/customitems - find the item to delete and click the link to see details./customitems/{id} - click the delete link to delete the item./customitems/{id}/delete - see a warning page about deleting, and click the delete link again./customitems/{id}/delete - browser sends a POST request to this URL to delete the item (this is invisible to the user)/customitems - browser is redirected back to the main pageAt the end of this project, you should update the UML diagram for the project to include the new web application classes. You may choose to make multiple diagrams showing more detail within each package, and a summary diagram showing the relationships between the packages.
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.
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 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 Starfleet Subs, based in the Star Trek universe.
The eleventh milestone involves adding form validation and serialization to the existing project, specifically targeted at custom menu items.
This milestone must follow these professional coding standards:
__init__.py and __main__.py are exempt.application plugin. The project should compile without errors.starfleetsubs.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.flake8-docstrings and pep8-naming plugins. Code should conform to PEP 8 style with Google style docstrings.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 3 characters.price of the custom menu item must be greater than or equal to 0, 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 greater than or equal to 0.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 /customitems 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.CustomItemController with the path /customitems/save that will save the existing custom items list to file by calling the new save method./customitems 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.
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 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:
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 Hero Pizza, celebrating the heroes from cartoons, comic books, movies, and more.
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:
heropizza.data.pizzas packageheropizza.data.sides packageheropizza.data.drinks packageheropizza.data.enums packageSee the Hero Pizza 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 pizzas and start there. Once you have the pizzas 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.
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: eat like a hero - choose pizza!
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 pizza should be stored in an appropriately named class in the heropizza.data.pizzas package. Each pizza should include an attribute for the following data:
Crust value (see below). It should have a getter and setter method.Veggie values (see below).
In addition, each entrée 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 Crust 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 pizza class should also override the default string representation method (toString() in Java or __str__() in Python) and return a string that properly describes the pizza. The string should be formatted as “{pizza name} on {crust} Crust”, such as “The Mikey on Thin Crust”.
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 pizza description will include a list of toppings included on the pizza. Those toppings 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 {topping}” message, such as “Hold Ham”, to be added to the Modifications list. Likewise, changing it back to true will remove the appropriate message. If all toppings are at their default values, the Modifications list should be empty.
Each pizza will be served on Thin Crust by default, and will include a default set of Veggies. Those attributes should be populated appropriately in the constructor for the pizza. Changes to the Crust and Veggies attributes will not affect the Modifications attribute at this time (we’ll add that later).
The number of Calories for a pizza will remain constant, regardless of other attributes (we’ll just pretend that changing the pizza doesn’t change the number of calories).
The Price for a pizza will change based on the value selected for the Crust. Each pizza will have a base price listed for the Thin crust option. Other crusts include an associated upcharge, which must be added to the base price.
just like the turtle himself, this sandwich “hams” it up and is super “cheesy”
heropizza.data.pizzas.TheMikey - The price is $8.25 and it is 986 calories. Toppings: Ham and Cheese. Veggies: Pineapple.
a simple pizza for a complex hero
heropizza.data.pizzas.TheJeanGrey - The price is $10.25 and it is 850 calories. Toppings: Pork and Cheese. Veggies: Mushrooms, Red Onions, Black Olives, Green Peppers, Banana Peppers and Roma Tomatoes
all the meat for a carnivorous feast
heropizza.data.pizzas.TheWolverine - The price is $9.35 and it is 950 calories. Toppings: Sausage, Bacon, Ham and Pork. Veggies: Red Onions and Green Peppers.
everyone “adora"s this classic
heropizza.data.pizzas.TheSheRa - The price is $8.75 and it is 1325 calories. Toppings: Pepperoni and Cheese. Veggies: none.
a star studded treat that isn’t a hologram
heropizza.data.pizzas.TheJem - The price is $9.65 and it is 1075 calories. Toppings: Chicken, BBQ Sauce and Bacon. Veggies: Red Onions
a pizza for a heroic appetite
heropizza.data.pizzas.TheHeMan - The price is $18.95 and it is 1986 calories. Toppings: Ham, Sausage, Pepperoni, Bacon, Pork, and Cheese. Veggies: Mushrooms, Red Onions, Black Olives, Green Peppers, Banana Peppers and Jalapeno Peppers
by your powers combined
heropizza.data.pizzas.TheCaptainPlanet - The price is $6.50 and it is 745 calories. Toppings: Cheese. Veggies: Mushrooms, Red Onions, Black Olives, Green Peppers, Banana Peppers, Jalapeno Peppers, Pineapple and Roma Tomatoes
Each side should be stored in an appropriately named class in the heropizza.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 “Small Snarf Sticks”.
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 Small.
soft breadsticks with a chewy bite
heropizza.data.sides.SnarfSticks - Small: $1.95 and 275 calories. Medium: $3.25 and 450 calories. Hero: $5.50 and **750 ** calories.
meatballs inspired by a famous hairdo
heropizza.data.sides.SailorMoon - Small: $2.35 and 300 calories. Medium: $4.85 and 550 calories. Hero: $7.95 and 960 calories.
do you have what it takes to wield Thor’s hammer?
heropizza.data.sides.Mjolnir - Small: $2.95 and 425 calories. Medium: $4.65 and 595 calories. Hero: $6.95 and 840 calories.
Batman’s trusty snack
heropizza.data.sides.Batwings - Small: $3.25 and 525 calories. Medium: $5.25 and 765 calories. Hero: $6.55 and 905 calories.
Each drink should be stored in an appropriately named class in the heropizza.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 “Small Katara”.
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 Modifications 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 Modifications list. Likewise, changing it back to true will remove the appropriate message.
If all flavors are at their default values, the Modifications list should be empty.
Each side description will include a Price and number of Calories for each Size. The sides will have a default size of Small. Changes to the Size attribute will not affect the Modification attribute.
a titan of a drink
heropizza.data.drinks.Starfire - Flavors: Cherry (default), Vanilla, Orange and Grape. Small: $1.40 and 170 calories. Medium: $3.75 and 255 calories. Hero: $4.75 and 375 calories.
a tasty drink made from strong roots
heropizza.data.drinks.Groot - Flavors: Caramel, Cinnamon, and Anise. Small: $3.55 and 320 calories. Medium: $4.45 and 435 calories. Hero: $5.05 and 540 calories.
a smooth drink to sooth a warrior’s spirit
heropizza.data.drinks.SamuraiJack - Flavors: Jackfruit (default), Banana, Mango and Strawberry. Small: $4.25 and 650 calories. Medium: $6.75 and 825 calories. Hero: $9.55 and 1115 calories.
a “powerpuff” of a drink with sugar and spice
heropizza.data.drinks.Bubbles - Flavors: Lychee, Passion Fruit, and Matcha. Small: $3.40 and 350 calories. Medium: $4.45 and 425 calories. Hero: $5.65 and 695 calories.
a simple water drink for an extraordinary water bender
heropizza.data.drinks.Katara - Flavors: Lemon and Coconut. All sizes are $1.00 and 0 calories.
Each enumeration should be stored in an appropriately named class in the heropizza.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.
a solid base for a trustworthy pizza slice
heropizza.data.enums.Crust - Thin, Hand Tossed (add $0.50), Deep Dish (add $1.00), Cheese Stuffed (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 crust type. Below are links to some sample code from later in this course that shows how to create such an enum and use that data.
options to fit any heroic appetite
heropizza.data.enums.Size - Small, Medium, Hero
an important part of a balanced meal
heropizza.data.enums.Veggie - Mushrooms, Red Onions, Black Olives, Green Peppers, Banana Peppers, Jalapeno Peppers, Pineapple, Roma Tomatoes
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 Hero Pizza, celebrating the heroes from cartoons, comic books, movies, and more.
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 pizza 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.ham 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("crust", Crust).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 pizzas and start there writing unit tests. Once you have the pizzas 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.
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 entrée test class should contain unit tests for the following:
ModificationsInitiallyEmpty() - the Modifications list should be empty when the object is createdHasCorrectCrustInitially() - the Crust attribute is initially set correctlyHasCorrectPriceForCrust(Crust) - the price is correct for each crust optionHasCorrectCalories() - the calories is correctStringIsCorrectForCrust(Crust) - call the toString() or __str__() method with each type of crust and verify the output.IncludesCorrectVeggiesByDefault(Veggie) - for each veggie, check if it is included or not by default.
boolean value indicating if the veggie should be included by default.AddRemoveVeggies(Veggie) - for each veggie, check that it can be added and removed, and the Veggies set will change accordingly.Has<Topping>ByDefault() - for each topping, check to see that it is included by default (returns true).
TheMikey would have a test method HasHamByDefault().Change<Topping>SetsModifications() - for each topping, check that changing it from and to the default value will add and remove the correct item from the Modifications list.
TheMikey would have ChangeHamSetsSpecialInstructions() that would confirm setting ham to false would add "Hold Ham" to the list of Modifications.ChangeMultipleToppingsModifications() - confirm that changing multiple toppings from their default values will add multiple items to the Modifications list.
SameObjectsAreEqual() - generate two different instances of the item, and confirm that they are equal using equals() (Java) or == (Python).DifferentCrustNotEqual() - generate two different instances of the item using different crust, and confirm that they are not equal using equals() (Java) or == (Python).DifferentToppingsNotEqual() - generate two different instances of the item using different sets of toppings, and confirm that they are not equal using equals() (Java) or == (Python).DifferentVeggiesNotEqual() - generate two different instances of the item using different sets of veggies, and confirm that they are not equal using equals() (Java) or == (Python).WrongObjectNotEqual() - generate an instance of the item and an instance of a different menu item, and confirm that they are not equal using equals() (Java) or == (Python). This should not throw an exception.Each side test class should contain unit tests for the following:
DefaultSizeCorrect() - each side should have the default size of Small when initially created.StringIsCorrectForSize(Size) - call the toString() or __str__() method with each size and verify the output.HasCorrectPriceForSize(Size) - the price is correct for each sizeHasCorrectCaloriesForSize(Size) - the calories is correct for each sizeSameObjectsAreEqual() - generate two different instances of the item, and confirm that they are equal using equals() (Java) or == (Python).DifferentSizeNotEqual() - generate two different instances of the item using different sizes, and confirm that they are not equal using equals() (Java) or == (Python).WrongObjectNotEqual() - generate an instance of the item and an instance of a different menu item, and confirm that they are not equal using equals() (Java) or -- (Python). This should not throw an exception.Each drink test class should contain unit tests for the following:
ModificationsInitiallyEmpty() - the Modifications list should be empty when the object is createdDefaultSizeCorrect() - each drink should have the default size of Small when initially created.StringIsCorrectForSize(Size) - call the toString() or __str__() method with each size and verify the output.HasCorrectPriceForSize(Size) - the price is correct for each sizeHasCorrectCaloriesForSize(Size) - the calories is correct for each sizeHas<Flavor>ByDefault() - for each flavor included by default, check to see that it is included (returns true). For example, Starfire would have a test method HasCherryByDefault().DoesNotHave<Flavor>ByDefault() - for each optional flavor not included by default, check to see that it is not included (returns false).
Starfire would have a test method DoesNotHaveVanillaByDefault().Change<Flavor>SetsModifications() - for each flavor, check that changing it from and to the default value will add and remove the correct item from the Modifications list.
Starfire would have ChangeCherrySetsModifications() that would confirm setting cherry to false would add "Hold Cherry" to the list of Modifications.ChangeMultipleFlavorsModifications() - confirm that changing multiple flavors from their default values will add multiple items to the Modifications list.
SameObjectsAreEqual() - generate two different instances of the item, and confirm that they are equal using equals() (Java) or == (Python).DifferentSizeNotEqual() - generate two different instances of the item using different sizes, and confirm that they are not equal using equals() (Java) or == (Python).DifferentFlavorsNotEqual() - generate two different instances of the item using different sets of flavors, and confirm that they are not equal using equals() (Java) or == (Python).WrongObjectNotEqual() - generate an instance of the item and an instance of a different menu item, and confirm that they are not equal using equals() (Java) or -- (Python). This should not throw an exception.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 Hero Pizza, celebrating the heroes from cartoons, comic books, movies, and more.
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:
heropizza.data.menu.Food interface that is implemented by all pizza, side, and drink classes
heropizza.data.pizzas.Pizza base classheropizza.data.sides.Side base classheropizza.data.drinks.Drink base classheropizza.data.menu.Menu that contains the full menu
Menu class should containFood interfaceMenu and Food 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:
Food Interface - 25%pizza Base Class - 10%Side Base Class - 10%Drink Base Class - 10%Menu Class - 20%Menu Unit Tests - 10%The following deductions apply:
This is not an exhaustive list of possible deductions. The instructors will strive to provide reasonable and fair grading, but we can’t predict all possible defects. It is up to the student to ensure that the project is complete and correct before submission.
Submit this assignment by creating a release on GitHub and uploading the release URL to the assignment on Canvas. You should not submit this Codio project or mark it as complete in Codio, in case you need to come back to it and make changes later.
The heropizza.data.menu.Food 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 (pizza, sides, and drinks) should be refactored to implement this interface. This will require some changes:
Pizza base class.Side base class.Accordingly, the unit tests for some of these classes will need updated, as discussed below.
Each of the three types of menu items should directly inherit from a new abstract base class. These classes should not be instantiated!
heropizza.data.pizzas.Pizza is the base class for all pizza items. It should include the following elements that are common to all pizza classes:
heropizza.data.sides.Side is the base class for all side items. It should include the following elements that are common to all side classes:
heropizza.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 Food 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 Food interface, so if you implement the interface at the base class level you do not need to redefine the abstract methods from the interface within the abstract base classes. Either approach is valid!
If you choose to inherit from the Food interface in the base classes in Python, the base class should not inherit from ABC - that is already covered as part of the interface. If you do, Mypy will present an error stating that it “cannot determine consistent method resolution order.”
You may also need to refactor some private attributes (with double underscores in Python) to protected attributes (single underscores in Python) as they move from the subclass to the superclass. In Java, these are just attributes as expected. In Python, it is simplest to declare those in the constructor of the superclass (such as self._size = Size.SMALL), then make sure you call that constructor using super().__init__() in the subclass’ constructor.
The heropizza.data.menu.Menu class should be a class that has static getter methods for these four elements:
pizzas - a list of Food elements containing an instance of all available pizzas (7 in total).sides - a list of Food elements containing an instance of all available sides. Since each side is available in three sizes, the list should include an instance of all three sizes of each side item (12 in total).drinks - a list of Food elements containing an instance of all available drinks. Since each drink is available in three sizes, the list should include an instance of all three sizes of each drink item (15 in total).fullmenu - a combined list of all menu items (34 in total).In Java, these lists should use a subclass of the List interface. In Python, these methods should use the built-in Python list data type. Since they are static methods, they cannot be constructed as Python properties using the @property decorator.
The following updates must be made to the existing unit tests in this project to accommodate these code changes:
Add:
InheritsFromPizza() - check if a given object inherits from the base Pizza class.ImplementsFood() - check if a given object implements the interface Food.ChangeVeggieSetsModifications(Veggie) - for each veggie, check that changing it from and to the default value will add and remove the correct item from the Modifications list.Update:
ModificationsInitiallyEmpty() should be renamed ModificationsInitiallyVeggies() and should now verify that the initial set of veggies is in the modifications list.Add:
InheritsFromSide() - check if a given object inherits from the base Side class.ImplementsFood() - check if a given object implements the interface Food.ModificationsEmpty() - check that the Modifications list is always empty.Add:
InheritsFromDrink() - check if a given object inherits from the base Drink class.ImplementsFood() - check if a given object implements the interface Food.To check for type compatibility, use the object instanceof Class operator in Java, or the isinstance(object, Class) method in Python as part of an assertion statement. Hamcrest also includes a few matchers for this, such as isA (Java) or instance_of() (Python).
Create a new test class for the Menu static class:
IncludesAllPizzas() - test that the pizzas list contains an instance of each pizza classIncludesAllSides() - test that the sides list contains an instance of each side class for each sizeIncludesAllDrinks() - test that the drinks list contains an instance of each drink class for each sizeIncludesAllItems() - test that the fullmenu list contains an instance of every menu item.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 Hero Pizza, celebrating the heroes from cartoons, comic books, movies, and more.
The fourth 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:
heropizza.Main class that properly loads and displays the program’s GUI.heropizza.gui.MainWindow class that represents the main GUI window.
heropizza.gui.OrderPanel class to represent the main order screen panel.
heropizza.gui.SidebarPanel class to represent the sidebar panel.
heropizza.gui.pizzas package for each pizza.
PizzaPanel class to reduce the amount of duplicate code.SidePanel in the heropizza.gui.sides package.
Side class. However, when buttons on the OrderPanel are clicked, you’ll need to make sure an instance of the correct item is generated.heropizza.gui.drinks package for each drink item.
DrinkPanel class to reduce the amount of duplicate code.heropizza.gui package do not require unit tests.heropizza.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.heropizza.gui package do require all appropriate documentation comments, and must be free of style errors.You are welcome to add additional methods to the existing content in the heropizza.data package. If so, make sure you include appropriate 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%MainWindow class - 4%SidebarPanel class - 4%OrderPanel 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.
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 pizza 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 settingsThen, 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 OrderPanel 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 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 Hero Pizza, celebrating the heroes from cartoons, comic books, movies, and more.
The fifth 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:
SidebarPanel panel.SidebarPanel 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 SidebarPanel, the following should happen:
It may be helpful to maintain a hash map or dictionary in the SidebarPanel class that associates nodes in the GUI tree element with the actual Food instances that they represent.
In addition, the following events should be implemented in the GUI:
When the Save button in any of the pizza, side, or drink panels is clicked, the following should happen:
SidebarPanel if it is a new item, or the item should be updated if it is being edited.MainWindow should be replaced with the OrderPanel (this was part of the previous milestone).When the Cancel button in any of the pizza, side, or drink panels is clicked, the following should happen:
MainWindow 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 SidebarPanel is clicked, the following should happen:
Food 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 Food.MainWindow and populated with the current status of 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:
Food 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 Food.SidebarPanel class.Unit tests should be added to the corresponding test package for the following classes:
heropizza.gui.pizzasheropizza.gui.drinksheropizza.gui.sides.SidePanel_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 MainWindow, OrderPanel, or SidebarPanel classes in this milestone._s
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:
heropizza.gui base package do not require unit tests, but all pizza, drink, and side panels require unit tests as outlined above.heropizza.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.heropizza.gui package and sub-packages do require all appropriate documentation comments, and must be free of style errors.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 pizza 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 Food 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.
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:
MainWindow.addItem(item) - basically a pass-through method that calls the SidebarPanel.addItem(item) method. This method would be accessible to all order item panels since they get a reference to the MainWindow instance.SidebarPanel.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.SidebarPanel.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 pizza panel test class should contain unit tests for the following:
testDefaultConstructor() - create the panel without providing an existing element, and assert that it creates a new instance of the correct item.testBadActionCommand() - call the actionPerformed() method with a bad action command, and assert that an exception is not thrown.testCrustComboBox(Crust) - instantiate a panel with an existing item, change the value of the crust combo box in the GUI to the crust value, and fire a “save” action, then verify that the item has the correct crust value.testCrustComboBoxSetCorrectly(Crust) - instantiate a panel with an existing item using the given crust, and assert that the crust combo box is set to the correct value.test<Ingredient>CheckBox() - instantiate a panel with an existing item, change the value of the ingredient check box in the GUI to a value, and fire a “save” action, then verify that the item has the correct value. Do this for both true and false.test<Ingredient>CheckBoxSetCorrectly() - instantiate a panel with an existing item with a given value for ingredient, and assert that the ingredient checkbox is set to the correct value. Do this for both true and false.testToppingCheckBox(Topping) - instantiate a panel with an existing item, change the value of the topping check box in the GUI to a value, and fire a “save” action, then verify that the item has the correct value. Do this for both true and false.testToppingCheckBoxSetCorrectly(Topping) - instantiate a panel with an existing item with a given value for topping, and assert that the topping checkbox is set to the correct value. Do this for both true and false.testCancelButton() - instantiate a panel with an existing item, change several values in the GUI, and fire a “cancel” action, then assert that the item is unchanged from its previous state.Each side panel test class should contain unit tests for the following:
testDefaultConstructor<Side>() - create the panel by providing an instance of each side class, and test that its item is set to an instance of that class.testBadActionCommand() - call the actionPerformed() method with a bad action command, and assert that an exception is not thrown.testSizeComboBox(Size) - instantiate a panel with an existing item, change the value of the size combo box in the GUI to the size value, and fire a “save” action, then verify that the item has the correct size value.testSizeComboBoxSetCorrectly(Size) - instantiate a panel with an existing item using the given size, and assert that the size combo box is set to the correct value.testCancelButton() - instantiate a panel with an existing item, change several values in the GUI, and fire a “cancel” action, then assert that the item is unchanged from its previous state.testConstructorEmptyItem() - create the panel by passing a null item, and verify that an exception is thrown.Each drink panel test class should contain unit tests for the following:
testDefaultConstructor() - create the panel without providing an existing element, and assert that it creates a new instance of the correct item.testBadActionCommand() - call the actionPerformed() method with a bad action command, and assert that an exception is not thrown.testSizeComboBox(Size) - instantiate a panel with an existing item, change the value of the size combo box in the GUI to the size value, and fire a “save” action, then verify that the item has the correct size value.testSizeComboBoxSetCorrectly(Size) - instantiate a panel with an existing item using the given size, and assert that the size combo box is set to the correct value.test<Ingredient>CheckBox() - instantiate a panel with an existing item, change the value of the ingredient check box in the GUI to a value, and fire a “save” action, then verify that the item has the correct value. Do this for both true and false.test<Ingredient>CheckBoxSetCorrectly() - instantiate a panel with an existing item with a given value for ingredient, and assert that the ingredient checkbox is set to the correct value. Do this for both true and false.testCancelButton() - instantiate a panel with an existing item, change several values in the GUI, and fire a “cancel” action, then assert that the item is unchanged from its previous state.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/heropizza/data --html=reports/pytest-data/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/heropizza/gui/pizzas --html=reports/pytest-pizzas/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/heropizza/gui/drinks test/heropizza/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 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 Hero Pizza, celebrating the heroes from cartoons, comic books, movies, and more.
The sixth 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.
heropizza.data.menu.Order - this class should represent a collection of Food objects that make up an order.
Food object is contained in the collection. Recall that this should use the identity test, not the equality test.Foods, with methods to add and remove items.
OrderNumberSingleton class discussed below. It should only include a getter.Order objects.heropizza.data.menu.Combo - this class should implement the Food interface, and represent a combo meal consisting of an pizza, two sides, and drink.
Pizza instance - the pizza in the comboSide instances - the sides 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.Food interface:
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.heropizza.data.menu.ComboBuilder - a class that implements the Builder Pattern to build the available combos described below.
Combo object indicated by the integer.heropizza.data.menu.OrderNumberSingleton - a class that implements the Singleton Pattern to generate new order numbers.
synchronized statement in Java or a lock in a with statement in Python).heropizza.gui.PanelFactory - a class that implements the Factory Method Pattern to return an instance of a GUI panel for a given pizza, side, or drink.
MainWindow 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.Food item, MainWindow parent) should accept an instance of an Food 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.Combos as Foods. We’ll address that in the next milestone.Menu - update to include the following items:
ComboBuilder class discussed below.OrderPanel - 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.SidebarPanel - 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.
SidebarPanel 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.
All new classes except PanelFactory should include full unit tests that achieve at or near 100% code coverage and adequately test all aspects of the class. In addition, some previous tests may need to be updated to match new requirements.
Java Only: You should also update the unit tests for each of the GUI panels created in the previous milestone to use a fake MainWindow object instead of creating one in the test. This should make the tests run much faster, and you should be able to see that the code in MainWindow is not executing in the code coverage report.
Python Only: Sadly, I have yet to figure out if it is possible to properly fake parts of tkinter such that the MainWindow class can be properly substituted with a fake. No changes are required at this time.
Once this milestone is complete, all classes in the following packages should have unit tests that achieve at or near 100% code coverage:
heropizza.data.*heropizza.gui.drinks.*heropizza.gui.pizzas.*heropizza.gui.sides.*The only classes that do not meet this requirement are MainWindow, OrderPanel, PanelFactory, and SidebarPanel in the heropizza.gui package.
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 - 10%Combo - 10%ComboBuilder - 10%OrderNumberSingleton - 5%PanelFactory - 5%Order - 15%Combo - 15%ComboBuilder - 5%OrderNumberSingleton - 5%Menu and unit tests: 5%OrderPanel: 5%SidebarPanel: 10%The following deductions apply:
This is not an exhaustive list of possible deductions. The instructors will strive to provide reasonable and fair grading, but we can’t predict all possible defects. It is up to the student to ensure that the project is complete and correct before submission.
Submit this assignment by creating a release on GitHub and uploading the release URL to the assignment on Canvas. You should not submit this Codio project or mark it as complete in Codio, in case you need to come back to it and make changes later.
The Mikey, Snarf Sticks, Mjolnir, Starfire
The Wolverine, Batwings, Sailor Moon, Groot
The He-Man, Snarf Sticks, Sailor Moon, Samurai Jack
The Jem, Sailor Moon, Batwings, Bubbles
The Captain Planet, Snarf Sticks, Mjolnir, Katara
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.
SizeIs0Initially() - the size of the order is initially 0.TotalsAre0Initially() - the subtotal, tax, and total are 0 initially.NegativeTaxRateThrowsException() - setting the tax rate to a negative value throws an exception.TaxRateOver100ThrowsException() - setting the tax rate to a value over 1.0 throws an exception.AddItemsUpdatesSize() - add a few fake items one at a time and check size after each one.AddItemsUpdatesTotals() - add a few fake items one at a time and check subtotal, tax, and total after each one.AddItemsUpdatesCalories() - add a few fake items one at a time and check calories after each one.ContainsUsesInstanceComparison() - confirm that the contains method uses instance comparison. Create two actual order items (this cannot be done with fakes) that will return true when 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.RemoveUsesInstanceComparison() - confirm that the remove method uses instance comparison. Create two actual order items (this cannot be done with fakes) that will return true when equals() is called. Place both in in the order, then remove one and confirm that the correct one was removed using contains. You may wish to do this twice, removing the first one added once and the second one added the second time.OrderNumberFromSingleton()- confirm that the Order class is using OrderNumberSingleton. Create a fake OrderNumberSingleton that returns a value for an order number, then instantiate an Order and verify that it received the given order number.TaxRateSetGlobally() - create two 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.RemoveMissingItemDoesNotThrow() - removing an item not in the order should not throw an exception.IteratorContainsItems() - add fake items to the order, get the iterator, and confirm that the fake items are returned in order.GetItemsByIndex() - add fake items to the order, and confirm that each one can be accessed via its index.ConstructorSetsName() - the constructor should set the name.ConstructorAcceptsNullName() - the constructor should accept null or None for the name.ConstructorSetsItemsToNull() - the constructor should set the pizza, sides, and drink elements to null or None.SetDiscountToNegativeThrowsException() - setting the discount to a negative value throws an exception.CanSetDiscountToZero() - setting the discount to 0 does not throw an exception.PriceZeroNoItems() - the price should be 0 if all items are null or None.CaloriesZeroNoItems() - the calories should be 0 if all items are null or None.PriceAllItems() - add fake items to combo and verify that the price is summed correctly (remember to take off the discount).CaloriesAllItems() - add fake items to combo and verify that the calories is summed correctly.NoDiscountWhenItemMissing() - add up to three items to the combo and verify that the price is correct and does not include discount.DiscountSetGlobally() - create two Combo instances, change the discount, and confirm that both use the new discount. This is best done by adding three items to each combo and checking the total price.ItemsListCorrect() - add fake items to the combo and verify that the list returned by items getter contains those items.ItemsListEmpty() - getting a list when the combo is empty results in an empty list.ModificationsHasDiscount() - modifications list should include a discount message if all combo items are populated.AddingComboToComboThrowsException() - adding a combo as an item to a combo throws an exception.TwoCombosEqual() - create two combos containing the same name and fake objects and test that they are equal.TwoCombosNotEqual() - create two combos with different names but the same fake objects, and test that they are not equal.TwoEmptyCombosEqual() - create two empty combos with null or None names and test that they are equal.TwoCombosOneEmptyNotEqual() - create two combos, one empty, one not, and test that they are not equal.DifferentObjectNotEqual() - confirm that equality test will return false when given a different type of object.You may need to add additional tests of the equals() method in Java to achieve 100% code coverage.
For these tests, I recommend just checking the types of the pizza, sides, and drink items in the Combo returned, as well as the name, rather than using any fake objects. As before, you may wish to make these attributes visible to the test.
Combo1() - Combo 1 is built correctlyCombo2() - Combo 2 is built correctlyCombo3() - Combo 3 is built correctlyCombo4() - Combo 4 is built correctlyCombo5() - Combo 5 is built correctlyBadComboThrowsException() - a bad combo number should throw an exceptionSequentialOrderNumbers - call getNextOrderNumber() several times and make sure each one is sequential.I ran into even more issues with Python not running unit tests in tox properly on this assignment. As before, it seems to be the same cause:
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/heropizza/data --html=reports/pytest-data/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/heropizza/gui/pizzas/test_TheMikeyPanel.py --html=reports/pytest-pizzas1/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/heropizza/gui/pizzas/test_TheJeanGreyPanel.py --html=reports/pytest-pizzas2/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/heropizza/gui/pizzas/test_TheWolverinePanel.py --html=reports/pytest-pizzas3/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/heropizza/gui/pizzas/test_TheSheRaPanel.py --html=reports/pytest-pizzas4/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/heropizza/gui/pizzas/test_TheJemPanel.py --html=reports/pytest-pizzas5/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/heropizza/gui/pizzas/test_TheHeManPanel.py --html=reports/pytest-pizzas6/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/heropizza/gui/pizzas/test_TheCaptainPlanetPanel.py --html=reports/pytest-pizzas7/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/heropizza/gui/drinks test/heropizza/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:
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 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 Hero Pizza, celebrating the heroes from cartoons, comic books, movies, and more.
The seventh milestone involves finalizing the GUI for creating 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.
It is best to think of this assignment as one consisting of two distinct parts.
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 the previous milestone.SidebarPanel 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:
MainWindow class/type as its parent, we can abstract that to a ParentPanel interface that is implemented by both the MainWindow class and ComboPanel. This allows the existing order item panels to use the new ComboPanel as its parent.ComboPanelComboPanel instead of MainWindow)MainWindow 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.All new and updated classes in this milestone should contain full documentation comments.
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.
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 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 now 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 indentions 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.
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 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.
Note that the window above only has a single side option, but the combo for this project requires two sides. So, you may have to adapt this layout to work in this case.
You may wish to review the Spinner (Java) or Spinbox (Python) GUI elements.
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 Hero Pizza, celebrating the heroes from cartoons, comic books, movies, and more.
The eighth 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.
heropizza.web package.heropizza.web.MenuController class to act as the controller. It should include the following routes:
/ - a home page for the application./info - an info page with the text given at the bottom of the page. You may add additional text and items as desired/order - a page that includes the entire menu (all predefined combos, pizzas, 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:
- Hero PizzaCreate 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 Hero Pizza! Our motto: eat like a hero - choose pizza!
info.html contains an <h1> tag with the title “About Hero Pizza” and the following text in a paragraph (you may add additional text as desired):Hero Pizza was developed as part of the CC 410 course at Kansas State University by <your name here>.
order.html contains the following content:
food-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.
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 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 Hero Pizza, celebrating the heroes from cartoons, comic books, movies, and more.
The ninth 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 “batwings” should not only return that side, but also combos 2 and 4 since those combos include that item.
Your search page should be accessible via the simplesearch 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<Food> items, String keywords) - returns Iterable<Food>filterTypes(Iterable<Food> items, boolean entree, boolean side, boolean drink, boolean combo) - returns Iterable<Food>
filterPrice(Iterable<Food> items, float min, float max) - returns Iterable<Food>filterCalories(Iterable<Food> items, int min, int max) - returns Iterable<Food>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.
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.
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 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 Hero Pizza, celebrating the heroes from cartoons, comic books, movies, and more.
The tenth 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 heropizza.data.menu.CustomMenuItem that can represent a custom menu item. It should implement the Food 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. You do not have to create any unit tests for this class.
Create a class heropizza.data.menu.CustomMenuItemList that represents a list of custom menu items. This class should implement both the Iterator design pattern (using the Iterable<CustomMenuItem> 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 CustomMenuItem objects, and provide methods for adding, retrieving, updating, and deleting those items. You may add additional utility methods as desired. 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 CustomMenuItemList data structure.
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 CustomMenuItemList 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.
You are encouraged to reuse the content from your existing template for displaying all menu items here. Each 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 update the UML diagram for the project to include the new web application classes. You may choose to make multiple diagrams showing more detail within each package, and a summary diagram showing the relationships between the packages.
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:
CustomMenuItem class - 10%CustomMenuItemList 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.
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 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 Hero Pizza, celebrating the heroes from cartoons, comic books, movies, and more.
The eleventh 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 5 characters.price of the custom menu item must be greater than or equal to 1.00, 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 greater than or equal to 100.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.
CustomMenuItemList 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.CustomMenutemList 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.
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 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 That’s a Wrap, offering wraps of all shapes and sizes to celebrate our favorite movies.
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:
thatsawrap.data.wraps packagethatsawrap.data.sides packagethatsawrap.data.drinks packagethatsawrap.data.enums packageSee the That’s a Wrap 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 wraps and start there. Once you have the wraps 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: be a star - wrap things your way!
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 wrap should be stored in an appropriately named class in the thatsawrap.data.wraps package. Each wrap should include an attribute for the following data:
Shell value (see below). It should have a getter and setter method.Addin values (see below).
In addition, each wrap 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 Shell 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 wrap class should also override the default string representation method (toString() in Java or __str__() in Python) and return a string that properly describes the wrap. The string should be formatted as “{wrap name} in a {shell} Shell”, such as “The Godfather in a Stromboli Shell”.
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 wrap description will include a list of ingredients included on the wrap. 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 Pepperoni”, 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 wrap will be served in a particular Default Shell, and will include a default set of Addins. Those attributes should be populated appropriately in the constructor for the wrap. Changes to the Shell and Addins attributes will not affect the Instructions attribute at this time (we’ll add that later).
The number of Calories for a wrap will remain constant, regardless of other attributes (we’ll just pretend that changing the wrap doesn’t change the number of calories).
The Price for a wrap will change based on the value selected for the Shell. Each wrap will have a base price listed for the Default Shell option. Other shells 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 shell. You may want to calculate and store a base price for the item by removing the upcharge from the menu price.
this wrap will make your taste buds an offer they can’t refuse
thatsawrap.data.wraps.Godfather - The price is $9.65 and it is 1268 calories. Served in a Stromboli Shell. Ingredients: Pepperoni, Sausage, Marinara and Cheese. Addins: Peppers and Onions.
an emerald city of flavors - truly a wrap of a different color
thatsawrap.data.wraps.Wizard - The price is $10.35 and it is 1085 calories. Served in a Spinach Shell. Ingredients: Chicken, Spinach, Cheese. Addins: Tomatoes and Dressing.
a hot and spicy classic
thatsawrap.data.wraps.SomeLike - The price is $11.45 and it is 1370 calories. Served in a Whole Grain Shell. Ingredients: Chicken, Cheese. Addins: Onions, Peppers and Buffalo Sauce.
a specialty from the city so nice they named it twice
thatsawrap.data.wraps.WestSide - The price is $8.75 and it is 1240 calories. Served in a Whole Grain Shell. Ingredients: Corned Beef, Cabbage and Cheese. Addins: Onions, Pickles and Mustard.
a massive wrap that can feed even the hungriest warrior
thatsawrap.data.wraps.Spartacus - The price is $16.55 and it is 1874 calories. Served in a Spinach Shell. Ingredients: Pepperoni, Sausage, Chicken, Corned Beef and Cheese. Addins: Peppers, Tomatoes, Onions, Pickles, Buffalo Sauce and Dressing.
Each side should be stored in an appropriately named class in the thatsawrap.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 “Indie Yankee Doodle Dandy”.
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 Indie.
stuck a feather in his cap and called it macaroni
thatsawrap.data.sides.Yankee - Indie: $2.25 and 400 calories. Studio: $3.95 and 650 calories. Blockbuster: $6.25 and 875 calories.
fried potatoes good enough to keep for yourself
thatsawrap.data.sides.French - Indie: $2.75 and 550 calories. Studio: $4.85 and 700 calories. Blockbuster: $5.25 and 950 calories.
guaranteed not to be poisoned or your money back
thatsawrap.data.sides.SnowWhite - Indie: $1.50 and 225 calories. Studio: $2.25 and 350 calories. Blockbuster: $3.00 and 475 calories.
Each drink should be stored in an appropriately named class in the thatsawrap.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 “Indie Forrest Gump”.
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 side description will include a Price and number of Calories for each Size. The sides will have a default size of Indie. Changes to the Size attribute will not affect the Instructions attribute.
you never know what you are going to get
thatsawrap.data.drinks.Forrest - Flavors: Chocolate (default), Vanilla, Caramel and Coffee. Indie: $5.25 and 980 calories. Studio: $7.50 and 1365 calories. Blockbuster: $9.00 and 1875 calories.
comes with a little umbrella, but you have to provide the song
thatsawrap.data.drinks.Singin - Flavors: Cherry (default), Strawberry, Cola and Grape. Indie: $2.75 and 360 calories. Studio: $3.25 and 400 calories. Blockbuster: $4.00 and 550 calories.
eye of the tiger not included
thatsawrap.data.drinks.Rocky - Flavors: Strawberry (default), Banana, Peach and Mango. Indie: $5.85 and 665 calories. Studio: $7.95 and 825 calories. Blockbuster: $9.45 and 1060 calories.
Each enumeration should be stored in an appropriately named class in the thatsawrap.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 setting for a delicious meal
thatsawrap.data.enums.Shell - Whole Grain (add $0.75), Spinach (add $1.00) or Stromboli (add $1.50)
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 shell. Below are links to some sample code from later in this course that shows how to create such an enum and use that data.
options to fit any budget
thatsawrap.data.enums.Size - Indie (Small), Studio (Medium), Blockbuster (Large)
the extras aren’t just in the background
thatsawrap.data.enums.Addins - Peppers, Onions, Tomatoes, Pickles, Dressing, Buffalo Sauce, Mustard
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 That’s a Wrap, offering wraps of all shapes and sizes to celebrate our favorite movies.
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 wraps 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.pepperoni 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("crust", Crust).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 wraps and start there writing unit tests. Once you have the wraps 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 That’s a Wrap, offering wraps of all shapes and sizes to celebrate our favorite movies.
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:
thatsawrap.data.menu.Item interface that is implemented by all wrap, side, and drink classes
thatsawrap.data.wraps.Wrap base classthatsawrap.data.sides.Side base classthatsawrap.data.drinks.Drink base classthatsawrap.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%Wrap 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 thatsawrap.data.menu.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 (wraps, sides, and drinks) should be refactored to implement this interface. This will require some changes:
Wrap base class.Side base class.Accordingly, the unit tests for some of these classes will need updated, as discussed below.
Each of the three types of menu items should directly inherit from a new abstract base class. These classes should not be instantiated!
thatsawrap.data.wraps.Wrap is the base class for all wrap items. It should include the following elements that are common to all wrap classes:
thatsawrap.data.sides.Side is the base class for all side items. It should include the following elements that are common to all side classes:
thatsawrap.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.INDIE), then make sure you call that constructor using super().__init__() in the subclass’ constructor.
The thatsawrap.data.menu.Menu class should be a class that has static getter methods for these four elements:
wraps - a list of Item elements containing an instance of all available wraps (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 That’s a Wrap, offering wraps of all shapes and sizes to celebrate our favorite movies.
The fourth 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:
thatsawrap.gui package to store all GUI code.thatsawrap.gui.wraps package to store all GUI panels for wraps.thatsawrap.gui.sides package to store all GUI panels for sides.thatsawrap.gui.drinks package to store all GUI panels for drinks.thatsawrap.Main class that properly loads and displays the program’s GUI.thatsawrap.gui.PrimaryWindow class that represents the main GUI window.
thatsawrap.gui.MenuPanel class to represent the main ordering screen panel.
thatsawrap.gui.OrderPanel class to represent the sidebar panel containing a user’s order.
thatsawrap.gui.wraps package for each wrap.
WrapPanel class to reduce the amount of duplicate code.SidePanel in the thatsawrap.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.thatsawrap.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:
thatsawrap.gui package do require all appropriate documentation comments, and must be free of style errors. Every method must include full documentation comments.thatsawrap.gui package do not require unit tests.thatsawrap.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.thatsawrap.gui package and how all GUI classes are related. You should also show any links to the classes in the thatsawrap.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 thatsawrap.data packages.
thatsawrap.gui.wraps package are all related to similar classes in the thatsawrap.data.wraps package without listing the individual classes in that package.You are welcome to add additional methods to the existing content in the thatsawrap.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 wrap 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 settingsThen, 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 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 That’s a Wrap, offering wraps of all shapes and sizes to celebrate our favorite movies.
The fifth 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.
When the Save button in any of the wrap, 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 wrap, 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:
thatsawrap.gui.wrapsthatsawrap.gui.drinksthatsawrap.gui.sidesSee 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:
thatsawrap.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.thatsawrap.gui base package do not require unit tests, but all wrap, drink, and side panels require unit tests as outlined above.thatsawrap.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 wrap 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/thatsawrap/data --html=reports/pytest-data/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/thatsawrap/gui/wraps --html=reports/pytest-wraps/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/thatsawrap/gui/drinks test/thatsawrap/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 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 That’s a Wrap, offering wraps of all shapes and sizes to celebrate our favorite movies.
The sixth 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 assignment will add several new classes to the project
thatsawrap.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.Items, with methods to add and remove items.
OrderNumberSingleton class discussed below. It should only include a getter.Order objects.thatsawrap.data.order.Combo - this class should implement the Item interface, and represent a combo meal consisting of a wrap, a side, and a drink.
Wrap instance - the wrap 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.thatsawrap.data.order.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.
thatsawrap.data.order.OrderNumberSingleton - a class that implements the Singleton Pattern to generate new order numbers.
synchronized statement in Java or a lock in a with statement in Python).thatsawrap.gui.PanelFactory - a class that implements the Factory Method Pattern to return an instance of a GUI panel for a given wrap, 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.Combos as Items. We’ll address that in the next milestone.There will also be several updates to existing classes.
Menu - update to include the following items:
ComboBuilder class discussed below.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!
All new classes except PanelFactory should include full unit tests that achieve at or near 100% code coverage and adequately test all aspects of the class. In addition, some previous tests may need to be updated to match new requirements.
Java Only: You should also update the unit tests for each of the GUI panels created in the previous milestone to use a fake PrimaryWindow object instead of creating one in the test. This should make the tests run much faster, and you should be able to see that the code in PrimaryWindow is not executing in the code coverage report.
Python Only: Sadly, I have yet to figure out if it is possible to properly fake parts of tkinter such that the PrimaryWindow class can be properly substituted with a fake. No changes are required at this time.
Once this milestone is complete, all classes in the following packages should have unit tests that achieve at or near 100% code coverage:
thatsawrap.data.*thatsawrap.gui.drinks.*thatsawrap.gui.wraps.*thatsawrap.gui.sides.*The only classes that do not meet this requirement are PrimaryWindow, OrderPanel, PanelFactory, and MenuPanel in the thatsawrap.gui package.
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 - 10%Combo - 10%ComboBuilder - 10%OrderNumberSingleton - 5%PanelFactory - 5%Order - 15%Combo - 15%ComboBuilder - 5%OrderNumberSingleton - 5%Menu and unit tests: 5%MenuPanel: 5%OrderPanel: 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 Godfather, The French Connection, Singin’ in the Rain
The Wizard of Oz, Snow White, Rocky
Spartacus, Yankee Doodle Dandy, Forrest Gump
Some Like It Hot, The French Connection, Forrest Gump
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 NoneCombo 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 wrap, side, and drink items in the Combo returned, as well as the name, rather than using any fake objects. As before, you may wish to make these attributes visible to the test.
getNextOrderNumber() several times and make sure each one is sequential.I ran into even more issues with Python not running unit tests in tox properly on this assignment. As before, it seems to be the same cause:
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/thatsawrap/data --html=reports/pytest-data/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/thatsawrap/gui/wraps/test_GodfatherPanel.py --html=reports/pytest-items1/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/thatsawrap/gui/wraps/test_WizardPanel.py --html=reports/pytest-items2/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/thatsawrap/gui/wraps/test_SomeLikePanel.py --html=reports/pytest-items3/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/thatsawrap/gui/wraps/test_WestSidePanel.py --html=reports/pytest-items4/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/thatsawrap/gui/wraps/test_SpartacusPanel.py --html=reports/pytest-items5/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/thatsawrap/gui/drinks test/thatsawrap/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:
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 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 That’s a Wrap, offering wraps of all shapes and sizes to celebrate our favorite movies.
The seventh milestone involves finalizing the GUI for creating 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.
It is best to think of this assignment as one consisting of two distinct parts.
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 the 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.ComboPanelComboPanel 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.All new and updated classes in this milestone should contain full documentation comments. All methods must be fully documented!
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.
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.
Note that the window above only has a single side option, but the combo for this project requires two sides. So, you may have to adapt this layout to work in this case.
You may wish to review the Spinner (Java) or Spinbox (Python) GUI elements.
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 That’s a Wrap, offering wraps of all shapes and sizes to celebrate our favorite movies.
The eighth 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.
thatsawrap.web package.thatsawrap.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, wraps, 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:
- That's a WrapCreate 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 That’s a Wrap! Our motto: be a star - wrap things your way!
about.html contains an <h1> tag with the title “About That’s a Wrap” and the following text in a paragraph (you may add additional text as desired):That’s a Wrap 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 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 That’s a Wrap, offering wraps of all shapes and sizes to celebrate our favorite movies.
The ninth 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 “wizard” should not only return that wrap, 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 wrap, 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 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 That’s a Wrap, offering wraps of all shapes and sizes to celebrate our favorite movies.
The tenth 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 thatsawrap.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 thatsawrap.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 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 That’s a Wrap, offering wraps of all shapes and sizes to celebrate our favorite movies.
The eleventh 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.
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.Items, 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 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 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.
OrderComboComboBuilderOrderNumberSingletonTest 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 NoneCombo 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 settingsThen, 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.entreesgamegrub.gui.drinksgamegrub.gui.sidesSee 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.ComboPanelComboPanel 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:
PanelFactoryOrderPanel - 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 GrubCreate 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.
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 Starfleet Subs, based in the Star Trek universe.
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:
sfsubs.data.entrees packagesfsubs.data.sides packagesfsubs.data.drinks packagesfsubs.data.enums packageSee the Starfleet Subs 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: to boldly eat a sandwich where no sandwich has been eaten before
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 sfsubs.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 “The Kirk on White Bread”.
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.
just like the man himself, this sandwich “hams” it up and is super “cheesy”
sfsubs.data.entrees.Kirk - The price is $7.35 and it is 650 calories. Served on White Bread with Ham and Cheese. Comes with Lettuce, Tomato, and Mayo.
a sandwich tasty enough for any “voyager” to enjoy
sfsubs.data.entrees.Janeway - The price is $10.35 and it is 950 calories. Served on White Bread with Ham, Pepperoni, Salami and Cheese. Comes with Lettuce, Tomato, Onion, Pickles, Peppers, and Mayo.
the ultimate judgement of humanity, a “continuum” of meats
sfsubs.data.entrees.Bbq - The price is $12.25 and it is 1375 calories. Served on White Bread with Brisket, Pulled Pork, Sausage, and Bacon. Comes with Onion, Pickles, and BBQ Sauce.
our “number one” sandwich
sfsubs.data.entrees.Riker - The price is $17.01 and it is 1701 calories. Served on Wheat Bread with Ham, Turkey, Pepperoni, Salami, Brisket, Pulled Pork, Bacon and Cheese. Comes with Lettuce, Tomato, Onion, Pickles, Peppers, Olives, Mayo, Mustard, and BBQ Sauce
a most logical choice
sfsubs.data.entrees.Spock - The price is $6.50 and it is 700 calories. Served on Wheat Bread with Cheese. Comes with Lettuce, Tomato, Onion, Pickles, Peppers, Olives, and Mayo.
Each side should be stored in an appropriately named class in the sfsubs.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 “Small Data Chips”.
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 Small.
crispy, crunchy potato chips seeking to understand human emotions
sfsubs.data.sides.Data - Small: $2.75 and 250 calories. Medium: $2.25 and 350 calories. Large: $3.50 and 550 calories.
a round cookie and two gherkin “nacelles” in honor of the best ship in the fleet
sfsubs.data.sides.Enterprise - Small: $2.98 and 170 calories. Medium: $3.77 and 340 calories. Large: $5.55 and 510 calories.
it is “futile” to “resist” these identical square pretzel bites wrapped in foil
sfsubs.data.sides.Borg - Small: $3.55 and 375 calories. Medium: $4.15 and 565 calories. Large: $6.65 and 780 calories.
Each drink should be stored in an appropriately named class in the sfsubs.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 “Small Picard”.
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 Small. Changes to the Size attribute will not affect the Instructions attribute.
tea, Earl Grey, hot
sfsubs.data.drinks.Picard - Tea served with Lemon. Can optionally add Ice. Small: $0.95 and 5 calories. Medium: $2.35 and 10 calories. Large: $2.25 and 15 calories.
the ultimate comfort drink inspired by a chocolate sundae
sfsubs.data.drinks.Troi - Espresso served with Chocolate, Whipped Cream and a Cherry. Can optionally add Extra Espresso Shot. Small: $3.75 and 300 calories. Medium: $4.35 and 425 calories. Large: $5.25 and 600 calories.
a warrior’s drink
sfsubs.data.drinks.Worf - Prune Juice. Can optionally add Ice. Small: $1.25 and 150 calories. Medium: $2.25 and 225 calories. Large: $2.55 and 415 calories.
Each enumeration should be stored in an appropriately named class in the sfsubs.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 upper deck and a lower deck is important for any sub
sfsubs.data.enums.Base - White Bread (no upcharge), Wheat Bread (add $0.50), Sourdough Bread (add $1.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.
options to fit any appetite
sfsubs.data.enums.Size - Small, Medium, Large
don’t forget your KHAAAAAANNNNN!-diments
sfsubs.data.enums.Topping - Lettuce, Tomato, Onion, Pickles, Peppers, Olives, Mayo, Mustard, BBQ Sauce
Special thanks to Nathan, Stephen, Sarah, Kellie, Dan, Jack, Josh, Pascal, Beth, and Vince 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 Starfleet Subs, based in the Star Trek universe.
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.ham 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 Starfleet Subs, based in the Star Trek universe.
The third milestone involves refactoring our code to take advantage of inheritance and the use of interfaces. We’ll also need to update our documentation and unit tests accordingly.
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:
sfsubs.data.Item interface that is implemented by all entree, side, and drink classes
sfsubs.data.entrees.Entree base classsfsubs.data.sides.Side base classsfsubs.data.drinks.Drink base classsfsubs.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 sfsubs.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!
sfsubs.data.entrees.Entree is the base class for all entree items. It should include the following elements that are common to all entree classes:
sfsubs.data.sides.Side is the base class for all side items. It should include the following elements that are common to all side classes:
sfsubs.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.SMALL), then make sure you call that constructor using super().__init__() in the subclass’ constructor.
The sfsubs.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 Starfleet Subs, based in the Star Trek universe.
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
sfsubs.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.Items, with methods to add and remove items.
OrderNumberSingleton class discussed below. It should only include a getter.Order objects.sfsubs.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.sfsubs.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.
sfsubs.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.
The Kirk, Enterprise, The Worf
The Riker, Data Chips, The Picard
The Janeway, Borg, The Troi
The Spock, Enterprise, The Picard
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 Starfleet Subs, based in the Star Trek universe.
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.
OrderComboComboBuilderOrderNumberSingletonTest 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:
sfsubs.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 NoneCombo 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 Starfleet Subs, based in the Star Trek universe.
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:
sfsubs.gui package to store all GUI code.sfsubs.gui.entrees package to store all GUI panels for entrees.sfsubs.gui.sides package to store all GUI panels for sides.sfsubs.gui.drinks package to store all GUI panels for drinks.sfsubs.Main class that properly loads and displays the program’s GUI.sfsubs.gui.PrimaryWindow class that represents the main GUI window.
sfsubs.gui.MenuPanel class to represent the main ordering screen panel.
sfsubs.gui.OrderPanel class to represent the sidebar panel containing a user’s order.
sfsubs.gui.entrees package for each entree.
EntreePanel class to reduce the amount of duplicate code.SidePanel in the sfsubs.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.sfsubs.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:
sfsubs.gui package do require all appropriate documentation comments, and must be free of style errors. Every method must include full documentation comments.sfsubs.gui package do not require unit tests at this time.sfsubs.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.sfsubs.gui package and how all GUI classes are related. You should also show any links to the classes in the sfsubs.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 sfsubs.data packages.
sfsubs.gui.entrees package are all related to similar classes in the sfsubs.data.entrees package without listing the individual classes in that package.You are welcome to add additional methods to the existing content in the sfsubs.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 settingsThen, 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 Starfleet Subs, based in the Star Trek universe.
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:
sfsubs.gui.entreessfsubs.gui.drinkssfsubs.gui.sidesSee 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:
sfsubs.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.sfsubs.gui base package do not require unit tests, but all entree, drink, and side panels require unit tests as outlined above.sfsubs.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/sfsubs/data --html=reports/pytest-data/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/sfsubs/gui/entrees --html=reports/pytest-entrees/index.html
python3 -m coverage run --parallel-mode --source src -m pytest test/sfsubs/gui/drinks test/sfsubs/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 Starfleet Subs, based in the Star Trek universe.
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.ComboPanelComboPanel 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
sfsubs.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:
sfsubs.data.*sfsubs.gui.drinks.*sfsubs.gui.entrees.*sfsubs.gui.sides.*The only classes that do not meet this requirement are PrimaryWindow, OrderPanel, PanelFactory, and MenuPanel in the sfsubs.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:
PanelFactoryOrderPanel - 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 Starfleet Subs, based in the Star Trek universe.
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 Starfleet Subs, based in the Star Trek universe.
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.
sfsubs.web package.sfsubs.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:
- About Starfleet SubsCreate 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 Starfleet Subs! Our motto: to boldly eat a sandwich where no sandwich has been eaten before!
about.html contains an <h1> tag with the title “About Starfleet Subs” and the following text in a paragraph (you may add additional text as desired):Starfleet Subs 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 Starfleet Subs, based in the Star Trek universe.
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 Starfleet Subs, based in the Star Trek universe.
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 sfsubs.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 sfsubs.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 Starfleet Subs, based in the Star Trek universe.
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.