Project 3: Frozen Yogurt with Mix-ins

Objectives:

Getting Help

This project sometimes takes students many, many hours. Please promise yourself that you will reach out to the CS Tutors or your instructor for help if you have already spent 10 or more hours on the project or if you have been stuck for more than 1 hour.

Assignment

For this project, you get to build off of the FrozenYogurt class from Project 2 and exercise using loops in Java! A very common application of loops is input validation. You will get to do that in this project. Additionally, you get to use either a StringBuilder or StringBuffer object to store multiple toppings in a FrozenYogurt object.

FrozenYogurt class

Building off of the requirements for the FrozenYogurt class in Project 2 make the following changes to that class:

  1. Change the instance variable for the topping to be either a StringBuilder or StringBuffer object to appropriately support a comma-separated list of toppings (instead of just a single topping). Note, leave the function headers the same for the setTopping and getTopping methods (have them take a String as an argument and return a String, respectively).
  2. Add an addTopping method that take a String as a parameter. If the instance variable already has a topping, then separate the previous value and the new value with ", ". Otherwise, just use the new topping as the value (without a ","). For each additional topping added, add $0.49 to the price (the first one is free :).
  3. Change the setPrice method so that it returns a String. If the new price is negative, do not update the price and return a String with the following value:
    ALERT: Unable to set <name>'s price to <price> (negative values are not allowed)
    Where <name> is the name of the frozen yogurt and <price> is the parameter's value. If the price is 100.0 or greater, do not update the price and return a String with the following value:
    ALERT: Unable to set <name>'s price to <price> (value is too high (>=100.00))
    Otherwise, update the price and return an empty string. Note, do not put this logical in the driver code. Put it in your FrozenYogurt class.
  4. Change setYogurtFlavor method so that it returns a String. If the new flavor is not "chocolate" nor "vanilla", do not update the base flavor and return a String with the following value:
    ALERT: <new yogurt flavor> is not one of the valid yogurt flavors (chocolate or vanilla)!
    Where <new yogurt flavor> is the value of the parameter. If the new flavor is valid, then return an empty string.
  5. Write a Javadoc for this class that includes at least a description, @author and @version tags. For each method, write a Javadoc that includes at least a description. For each parameter in each method, include the @param tag. For each method that has a return type that is not void, include a @return tag.
  6. Note: The test cases require that this class have an appropriate constructor that does not have any parameters.

FrozenYogurtDriverWithMixins class

For this project, write a main() method in a FrozenYogurtDriverWithMixins class so that it completes the following (in the order given).

  1. Welcomes the user (using at least the phrase "Welcome")
  2. Asks the user if they would like a frozen yogurt (using at least the phrase "add a frozen yogurt"). If the user does not enter "yes" and they did not enter "no", then display the following message:
    Sorry, "<text entered>" is neither yes nor no
    Where <text entered> is the user's input. Repeatedly ask the user until either "yes" or "no" is entered. Note, repeat the prompt with the phrase "add a frozen yogurt" each time the user is prompted to enter the name of the yogurt.
  3. Prompt the user to enter the name of frozen yogurt. Use at least "name and "yogurt" in the prompt.
  4. Prompt the user to enter the price of the frozen yogurt. Use at least the term "price" in each prompt. (Notice that this is a different order of inputs than in Project 2.) Repeatedly ask the user for a valid price if one is not given (and display the appropriate message from setPrice when an invalid is given). Repeat the prompt each time. You can assume that the user will only input numbers for the price.
  5. Prompt the user to enter their selection for the base yogurt flavor. Use at least the term "base" in each prompt. Repeatedly prompt the user until the setYogurtFlavor method returns an empty string.
  6. Prompt the user for the (initial) topping for the frozen yogurt. Use the term "topping" in the prompt. Allow the topping to be multiple words (your Project 2 may not have supported this).
  7. Ask the user if they would like to add a topping. Use the phrase "another topping" in the prompt. As indicated above, repeatedly prompt the user if they did not enter "yes" and they did not enter "no". Display the same error message as indicated above. If the user enters "yes", then prompt them for the name of the topping. Use the term "additional" in the prompt. Again, allow the user to enter in a topping that is multiple words. After each additional topping is entered, ask the user again if they would like to add another topping. Use the same prompt as the first time.
  8. Display a description of the frozen yogurt object by calling its description method.
  9. Display "Thank you!" before terminating the program.

Allow the yogurt base flavor and topping names to be multiple words (to accomplish this, you probably want to use only calls to nextLine on your Scanner object to get input from the user. To get the price, pass the string that nextLine returns to the parseDouble method in the Double class to get a double from the inputted String).

Write Javadoc for this class and Javadocs for each method as well.

codePost does not support the package statement. If your IDE inserted one, I configured codePost to automatically remove it.

Examples

Note, user input is in bold face blue and underlined text is required for test cases.

Example 1 (with invalid input)

Welcome PUT YOUR ORIGINAL WELCOME MESSAGE HERE

Would you like to add a frozen yogurt (yes/no)? maybe
You entered: maybe
Sorry, "maybe" is neither yes nor no
Would you like to add a frozen yogurt (yes/no)? deciding
You entered: deciding
Sorry, "deciding" is neither yes nor no
Would you like to add a frozen yogurt (yes/no)? yes
You entered: yes
Please enter the name of the frozen yogurt: Berry Delight
You entered: Berry Delight
Please enter the price for the Berry Delight: -50.0
You entered: -50.0
ALERT: Unable to set Berry Delight's price to -50.0 (negative values are not allowed)
Please enter the price for the Berry Delight: 999.99
You entered: 999.99
ALERT: Unable to set Berry Delight's price to 999.99 (value is too high (>=100.00))
Please enter the price for the Berry Delight: -1.0
You entered: -1.0
ALERT: Unable to set Berry Delight's price to -1.0 (negative values are not allowed)
Please enter the price for the Berry Delight: 4.5
You entered: 4.5
Please enter the base yogurt flavor for Berry Delight: Blueberry
You entered: Blueberry
ALERT: Blueberry is not one of the valid yogurt flavors (chocolate or vanilla)!
Please enter the base yogurt flavor for Berry Delight: blueberry
You entered: blueberry
ALERT: blueberry is not one of the valid yogurt flavors (chocolate or vanilla)!
Please enter the base yogurt flavor for Berry Delight: vanilla
You entered: vanilla
Please enter the topping to add to Berry Delight: blueberries
You entered: blueberries
Would you like to add another topping frozen yogurt (yes/no)? thinking
You entered: thinking
Sorry, "thinking" is neither yes nor no
Would you like to add another topping frozen yogurt (yes/no)? still
You entered: still
Sorry, "still" is neither yes nor no
Would you like to add another topping frozen yogurt (yes/no)? thinking
You entered: thinking
Sorry, "thinking" is neither yes nor no
Would you like to add another topping frozen yogurt (yes/no)? yes
You entered: yes
Please enter the additional topping flavor: blackberries
You entered: blackberries
Would you like to add another topping frozen yogurt (yes/no)? yes
You entered: yes
Please enter the additional topping flavor: strawberries
You entered: strawberries
Would you like to add another topping frozen yogurt (yes/no)? no
You entered: no

Frozen Yogurt : Berry Delight
Price         : $5.48
Yogurt        : vanilla
Topping(s)    : blueberries, blackberries, strawberries

Thank you!

Notice that multiple invalid values are entered and that the program keeps asking for a valid values until it gets a valid one. Also notice that all money values displayed by the program are rounded to two decimal places.

Example 2 (with all valid input)

Welcome PUT YOUR ORIGINAL WELCOME MESSAGE HERE

Would you like to add a frozen yogurt (yes/no)? yes
You entered: yes
Please enter the name of the frozen yogurt: Raspberry Cheesecake
You entered: Raspberry Cheesecake
Please enter the price for the Raspberry Cheesecake: 5.5
You entered: 5.5
Please enter the base yogurt flavor for Raspberry Cheesecake: vanilla
You entered: vanilla
Please enter the topping to add to Raspberry Cheesecake: raspberries
You entered: raspberries
Would you like to add another topping frozen yogurt (yes/no)? yes
You entered: yes
Please enter the additional topping flavor: crackers
You entered: crackers
Would you like to add another topping frozen yogurt (yes/no)? no
You entered: no

Frozen Yogurt : Raspberry Cheesecake
Price         : $5.99
Yogurt        : vanilla
Topping(s)    : raspberries, crackers

Thank you!

Example 3

Welcome PUT YOUR ORIGINAL WELCOME MESSAGE HERE

Would you like to add a frozen yogurt (yes/no)? nah
You entered: nah
Sorry, "nah" is neither yes nor no
Would you like to add a frozen yogurt (yes/no)? never
You entered: never
Sorry, "never" is neither yes nor no
Would you like to add a frozen yogurt (yes/no)? no
You entered: no
Thank you!

Bonuses

  1. Submit your project (.java files to codePost and the rubric to CougarVIEW) at least 24 hours before the due time and earn at least 90% of points.
  2. Generate the documentation (in HTML format) using javadoc. (Note, it should look like the documentation pages at docs.oracle.com.) If you're using BlueJ, then go to the Tools menu, the Program Documentation. Review the documentation to make sure that its complete. Upload a screenshot of how a browser displays the HTML file for your FrozenYogurt class to CougarVIEW. Additionally, create a compressed zip file of all of the files produced by javadoc. Submit your .zip to CougarVIEW

Rubric:

Points      Item
----------  --------------------------------------------------------------
_____ / 15  Style
            + Code is indented correctly
            + Methods should be no longer than 1 page
            + Documentation: (written for another software developer)
              * All source code files include Javadoc header block with description, @author, @version, etc.
              * Javadoc (with block tags, for example @param, @return) before each method
              * All non-trivial variables are commented
              * Comments included before major portions of code
_____ /     Compiles (max of 50% if it doesn't compile)
_____ / 83  codePost tests
_____ /  5  Complete HTML documentation (bonus)
_____ /  5  Submitted 1+ days early (bonus)
_____ /  2  Completed rubric (estimates for each line including hours spent)

_____ /100  Total


_____  Approximate number of hours spent

I, (REPLACE WITH YOUR FULL NAME), affirm that the code that I submitted is my own work and that I did not receive help that was not authorized by the instructor.

Copy and paste this rubric into a rubric-FrozenYogurtWithMixins.txt file (not a .docx, .doc nor .rtf file). Think of this as a checklist to ensure that you receive the maximum points possible. For each grade item, fill in your estimate for the grade you deserve. Additionally, include your estimate of how many hours your spent. Lastly, replace, "(REPLACE WITH YOUR FULL NAME)" with your full name to indicate that what you are submitting is entirely your own work.

Submission

The submission process has two parts:

  1. codePost

    Submit your FrozenYogurt class and your FrozenYogurtDriverWithMixins class to codePost.io. To register for a free codePost account, please follow these instructions. You can submit to codePost multiple times if you want. Only your last submission will be graded. Watch this short video for a demonstration of submitting an assignment and reviewing the results:
    YouTube video: codePost: Submission and Checking Results Thumbnail

  2. CougarVIEW

    Submit your rubric-FrozenYogurtWithMixins.txt to the appropriate Assignment tab/folder in CougarVIEW. This is required to receive detailed graded feedback on your project. If you resubmit your rubric, this will effectively replace your previous submission.

Help

  1. Do not ask for user input in your FrozenYogurt class. Also, do not display anything in your FrozenYogurt class.
  2. Only have one Scanner object in your program.
  3. You probably want to use the equals() method from the String class to test if the user entered "yes" or "no". It takes a String as a parameter and returns true if the values of the two Strings are the same and false otherwise. In the following example, nothing would be displayed:
    String professorsLastName          = "Carroll";
    String professorsLastNameMispelled = "Carrol";
    
    if( professorsLastName.equals( professorsLastNameMispelled ) == true ){
        System.err.println("Something wrong happened!");
    }
  4. One way to approach input validation is with the following structure:
    // Prompt user
    // Read input from user
    // echo input (helpful for knowing what the autograder entered)
    while( invalid_input_expression ){
        // Display error message
        // Prompt user
        // Read input from user
        // echo input (helpful for knowing what the autograder entered)
    }
    Alternatively, you could express the while loop as follows:
    while( !( valid_input_expression ) ){
  5. codePost uses Java version 8. You are required to not use Java syntax that requires a newer version.

Optional

The following are optional tasks that will not negatively affect your grade so long as implementing them does not disrupt the grading procedure of the requirements above:
  1. Run your Java code through a static code analysis tool and review the results.
  2. Enforce that two decimal places are displayed for the dollar amounts. To do so, you might want to look into the getCurrencyInstance() method in the NumberFormat class.