In: Computer Science
IN JAVA
Laboratory 3: Ice Cream!
Download Lab03.zip from ilearn and extract it into your working lab 3 directory
In this lab, you will be writing a complete class from scratch, the IceCreamCone class. You will also write a driver to interact with a user and to test all of the IceCreamCone methods.
Lab:
• Cone
• Ice Cream
o Flavor
o Topping
• Ice Cream Cone
• Driver
Part I: Cone
An ice cream cone has two main components, the flavor of ice cream and the type of cone. Write a Cone class that takes an integer in its constructor. Let a 1 represent a sugar cone, let a 2 represent a waffle cone, and let a 3 represent a cup. It will help to use a private variable in order to keep track of the cone type amongst your methods. Make sure to set an invalid entry to a default cone (the choice of default is up to you). Write a method to return the price of the cone. The sugar cone is $0.59, the waffle cone is $0.79, and the cup is free. Write a toString() method to return a String indicating the type of cone that was selected.
Note: If you need a carriage return in a String, use "\r\n"
Part II: Ice Cream
Download the following files:
• Topping.java
o public double price() //toppings are $0.15 ("no topping" is
free)
• Toppings.java //this file has the following public
interface:
o public static Toppings getToppings() //singleton design
pattern
o public int numToppings() //the number of different toppings
o public String listToppings() //list (and number) available
toppingso public Topping getTopping(int index) //1-based
Flavor.java
Flavors.java //this file has the following public interface:
o public static Flavors getFlavors() //singleton design
pattern
o public int numFlavors() //the number of different flavors
o public String listFlavors() //list (and number) available
flavorso public Flavor getFlavor(int index) //1-based
Ice cream has a number of scoops, a flavor, and a topping. Write an IceCream constructor that accepts the number of scoops (up to 3), a Flavor object, and a Topping object. It will help to use private variables in order to keep track of the number of scoops, your flavor, and your topping amongst your methods. Set default values (up to you) if the input is invalid (make sure to protect against null). Write a method to return the price
(each scoop over 1 adds $0.75 to the cost of the ice cream) and a method to return a String listing the ice cream parameters selected.
Part III: Ice Cream Cone
Download the following file:
• Currency.class //this file has the following public
interface:
o public static String formatCurrency(double val) //formats the
double as a String representing US
currency
It will help to use private variables in order to keep track of your cone and ice cream amongst your methods. Use Currency.class to format the total price of the Ice Cream Cone.
Note: Without using the Currency class, it is possible to get final prices that are not quite correct, such as 3.5300000000000002.
The IceCreamCone is composed of the Cone and the IceCream. Write a constructor that accepts an IceCream
and a Cone (protect against null), a method to return the price (the base price is $1.99 plus any costs
associated with the components), and a method to return a String display of the ice cream cone ordered by the
user.
Part IV: Ice Cream Driver
Download the following file:
• Keyboard.class //this file has the following public
interface:
o public static Keyboard getKeyboard() //singleton design patterno
public int readInt(String prompt)
o public double readDouble(String prompt)
o public String readString(String prompt)
defensive programming
In addition to main, include the following methods in your driver:
This is
Write a driver to obtain the ice cream cone order from the user. Allow multiple ice cream cones to be ordered,
and keep a
running total
of the price of the ice cream cones. Of course, wait (loop) for the user to input valid
entries. Thus, you are checking for valid entries in the driver and in the constructor of your objects.
, although it results in some code duplication.
public static Flavor getFlavorChoice() //look at the methods available in the Flavors class
public static Topping getToppingChoice() //look at the methods available in the Toppings class
public static int getScoopsChoice()
public static Cone getConeChoice()
All of these methods take input from the user (using
Keyboard.class) Example output included as a jpg in Lab03
files.
To compile: javac *.java
To run: java IceCreamDriver
You can also run your driver with my input file via: java IceCreamDriver < ice_cream.txt (or by running make.bat)
CURRENCY.JAVA
import java.text.DecimalFormat;
public class Currency
{
private final static DecimalFormat fmt = new
DecimalFormat("#,##0.00");
public static String formatCurrency(double val)
{
String temp = "$" + fmt.format(val);
return temp;
}
}
TOPPING.JAVA
public enum Topping
{
nuts(0.15), m_and_ms(0.15), hot_fudge(0.15), oreo_cookies(0.15),
no_topping(0.00);
private double toppingPrice;
private Topping(double price)
{
toppingPrice = price;
}
public double price()
{
return toppingPrice;
}
}
TOPPINGS.JAVA
public class Toppings
{
private static Toppings toppings = new Toppings();
private Topping[] all_toppings;
private Toppings()
{
all_toppings = Topping.values();
}
public static Toppings getToppings()
{
return toppings;
}
public int numToppings()
{
return all_toppings.length;
}
public String listToppings()
{
int index = 1;
//loop through the enumeration, listing the flavors
String topping_str = "";
for (Topping top : all_toppings)
{
topping_str += index + ". " + top.toString() + "\r\n";
index++;
}
return topping_str;
}
public Topping getTopping(int index) //1-based
{
int num_toppings = numToppings();
if (index < 1 || index > num_toppings)
{
index = 1;
}
return all_toppings[index - 1];
}
}
FLAVOR.JAVA
public enum Flavor
{
chocolate, vanilla, coffee, mint_chocolate_chip, almond_fudge,
pistachio_almond,
pralines_and_cream, cherries_jubilee, oreo_cookies_and_cream,
peanut_butter_and_chocolate,
chocolate_chip, very_berry_strawberry, rocky_road, butter_pecan,
chocolate_fudge, french_vanilla,
nutty_coconut, truffle_in_paradise;
}
FLAVORS.JAVA
public class Flavors
{
private static Flavors flavors = new Flavors();
private Flavor[] all_flavors;
private Flavors()
{
all_flavors = Flavor.values();
}
public static Flavors getFlavors()
{
return flavors;
}
public int numFlavors()
{
return all_flavors.length;
}
public String listFlavors()
{
int index = 1;
//loop through the enumeration, listing the flavors
String flavor_str = "";
for (Flavor flavor : all_flavors)
{
flavor_str += index + ". " + flavor.toString() + "\r\n";
index++;
}
return flavor_str;
}
public Flavor getFlavor(int index)
{
int num_flavors = numFlavors();
if (index < 1 || index > num_flavors)
{
index = 1;
}
return all_flavors[index - 1];
}
}
KEYBOARD.JAVA
public class Keyboard
{
private static Keyboard kb = new Keyboard();
/** The SDK provided Scanner object, used to obtain keyboard
input */
private java.util.Scanner scan;
private Keyboard()
{
scan = new java.util.Scanner(System.in);
}
public static Keyboard getKeyboard()
{
return kb;
}
/**
* Reads an integer from the keyboard and returns it.
* Uses the provided prompt to request an integer from the
user.
*/
public int readInt(String prompt)
{
System.out.print(prompt);
int num = 0;
try
{
num = scan.nextInt();
readString(""); //clear the buffer
}
catch (java.util.InputMismatchException ime) //wrong type
inputted
{
readString(""); //clear the buffer
num = 0;
}
catch (java.util.NoSuchElementException nsee) //break out of
program generates an exception
{
readString(""); //clear the buffer
num = 0;
}
return num;
}
/**
* Reads a double from the keyboard and returns it.
* Uses the provided prompt to request a double from the user.
*/
public double readDouble(String prompt)
{
System.out.print(prompt);
double num = 0.0;
try
{
num = scan.nextDouble();
readString(""); //clear the buffer
}
catch (java.util.InputMismatchException ime)
{
readString(""); //clear the buffer
num = 0;
}
catch (java.util.NoSuchElementException nsee)
{
readString(""); //clear the buffer
num = 0;
}
return num;
}
/**
* Reads a line of text from the keyboard and returns it as a
String.
* Uses the provided prompt to request a line of text from the
user.
*/
public String readString(String prompt)
{
System.out.print(prompt);
String str = "";
try
{
str = scan.nextLine();
}
catch (java.util.NoSuchElementException nsee)
{
readString(""); //clear the buffer
str = "";
}
return str;
}
}
//Java code
import java.text.DecimalFormat; public class Currency { private final static DecimalFormat fmt = new DecimalFormat("#,##0.00"); public static String formatCurrency(double val) { String temp = "$" + fmt.format(val); return temp; } }
//===============================================
public enum Topping { nuts(0.15), m_and_ms(0.15), hot_fudge(0.15), oreo_cookies(0.15), no_topping(0.00); private double toppingPrice; private Topping(double price) { toppingPrice = price; } public double price() { return toppingPrice; } }
//=======================================
public class Toppings { private static Toppings toppings = new Toppings(); private Topping[] all_toppings; private Toppings() { all_toppings = Topping.values(); } public static Toppings getToppings() { return toppings; } public int numToppings() { return all_toppings.length; } public String listToppings() { int index = 1; //loop through the enumeration, listing the flavors String topping_str = ""; for (Topping top : all_toppings) { topping_str += index + ". " + top.toString() + "\r\n"; index++; } return topping_str; } public Topping getTopping(int index) //1-based { int num_toppings = numToppings(); if (index < 1 || index > num_toppings) { index = 1; } return all_toppings[index - 1]; } }
//======================================
public enum Flavor { chocolate, vanilla, coffee, mint_chocolate_chip, almond_fudge, pistachio_almond, pralines_and_cream, cherries_jubilee, oreo_cookies_and_cream, peanut_butter_and_chocolate, chocolate_chip, very_berry_strawberry, rocky_road, butter_pecan, chocolate_fudge, french_vanilla, nutty_coconut, truffle_in_paradise; }
//================================================
public class Flavors { private static Flavors flavors = new Flavors(); private Flavor[] all_flavors; private Flavors() { all_flavors = Flavor.values(); } public static Flavors getFlavors() { return flavors; } public int numFlavors() { return all_flavors.length; } public String listFlavors() { int index = 1; //loop through the enumeration, listing the flavors String flavor_str = ""; for (Flavor flavor : all_flavors) { flavor_str += index + ". " + flavor.toString() + "\r\n"; index++; } return flavor_str; } public Flavor getFlavor(int index) { int num_flavors = numFlavors(); if (index < 1 || index > num_flavors) { index = 1; } return all_flavors[index - 1]; } }
//=======================================
public class Cone { private String coneType; /** * takes an integer in its constructor. Let a 1 represent * a sugar cone, * let a 2 represent a waffle cone, and let a 3 represent a cup. * @param cone */ public Cone(int cone) { if(cone==1) { coneType ="Sugar Cone"; } else if(cone ==2) { coneType ="Waffle cone"; } else if(cone ==3) { coneType = "Cup"; } /** * set an invalid entry to a default cone * (the choice of default is up to you) */ else { coneType ="Sugar Cone"; } } /** * a method to return the price of the cone. * The sugar cone is $0.59, * the waffle cone is $0.79, and the cup is free. * @return */ public double getPrice() { if(coneType.equals("Sugar Cone")) return 0.59; else if(coneType.equals("Waffle cone")) return 0.79; else return 0; } /** * * @return indicating the type of cone that was selected. */ @Override public String toString() { return ("Cone Type: "+coneType+"\r\n"); } }
//==========================================
public class IceCream { private Flavor flavor; private Topping topping; int numberOfScoops; private static double SCOOP_PRICE = 0.75; /** * an IceCream constructor that accepts the number of scoops] * (up to 3), a Flavor object, and a Topping object. * It will help to use private variables in order to keep * track of the number of scoops, your flavor, and your topping * amongst your methods. Set default values (up to you) * if the input is invalid (make sure to protect against null) * @param flavor * @param topping * @param numberOfScoops */ public IceCream(Flavor flavor, Topping topping, int numberOfScoops) { if(flavor==null) { flavor = Flavor.butter_pecan; } else { this.flavor = flavor; } if(topping==null) { topping =Topping.hot_fudge; } else { this.topping = topping; } if(numberOfScoops<1 || numberOfScoops>3) { this.numberOfScoops = 1; } else { this.numberOfScoops = numberOfScoops; } } public double getPrice() { return (numberOfScoops*SCOOP_PRICE+topping.price()); } /** * * @return a String listing the ice cream parameters selected. */ @Override public String toString() { return "Number Of Scoops: "+numberOfScoops+"\nTopping: "+topping.toString()+"\nFlavor: "+flavor.toString()+"\r\n"; } }
//=============================================
public class IceCreamCone { /** * IceCreamCone is composed of the Cone and the IceCream. */ private IceCream iceCream; private Cone cone; /** * a constructor that accepts an IceCream * and a Cone (protect against null), * @param iceCream * @param cone */ public IceCreamCone(IceCream iceCream, Cone cone) { if(iceCream==null) { iceCream = new IceCream(Flavor.butter_pecan,Topping.hot_fudge,2); this.iceCream = iceCream; } else { this.iceCream = iceCream; } if(cone==null) { cone = new Cone(2); } else { this.cone = cone; } } private final static double BASE_PRICE = 1.99; /** * @return the price (the base price is $1.99 plus any cost) */ public double getPrice() { return BASE_PRICE+cone.getPrice()+iceCream.getPrice(); } /** * * @return a method to return a String display * of the ice cream cone ordered by the * user. */ @Override public String toString() { return iceCream+" "+cone+" "+getPrice()+"\r\n"; } }
//=========================================
public class Keyboard { private static Keyboard kb = new Keyboard(); /** The SDK provided Scanner object, used to obtain keyboard input */ private java.util.Scanner scan; private Keyboard() { scan = new java.util.Scanner(System.in); } public static Keyboard getKeyboard() { return kb; } /** * Reads an integer from the keyboard and returns it. * Uses the provided prompt to request an integer from the user. */ public int readInt(String prompt) { System.out.print(prompt); int num = 0; try { num = scan.nextInt(); readString(""); //clear the buffer } catch (java.util.InputMismatchException ime) //wrong type inputted { readString(""); //clear the buffer num = 0; } catch (java.util.NoSuchElementException nsee) //break out of program generates an exception { readString(""); //clear the buffer num = 0; } return num; } /** * Reads a double from the keyboard and returns it. * Uses the provided prompt to request a double from the user. */ public double readDouble(String prompt) { System.out.print(prompt); double num = 0.0; try { num = scan.nextDouble(); readString(""); //clear the buffer } catch (java.util.InputMismatchException ime) { readString(""); //clear the buffer num = 0; } catch (java.util.NoSuchElementException nsee) { readString(""); //clear the buffer num = 0; } return num; } /** * Reads a line of text from the keyboard and returns it as a String. * Uses the provided prompt to request a line of text from the user. */ public String readString(String prompt) { System.out.print(prompt); String str = ""; try { str = scan.nextLine(); } catch (java.util.NoSuchElementException nsee) { readString(""); //clear the buffer str = ""; } return str; } }
//========================================
public class IceCreamDriver { public static void main(String[] args) { double totalPrice =0.0; while (true) { menu(); int choice = Keyboard.getKeyboard().readInt("Enter your choice: "); switch (choice) { case 1: Cone cone = getConeChoice(); System.out.println(cone); System.out.println("Cone price: "+Currency.formatCurrency(cone.getPrice())); totalPrice+= cone.getPrice(); break; case 2: Flavor flavor = getFlavorChoice(); Topping topping = getToppingChoice(); int scoops = getScoopsChoice(); IceCream iceCream = new IceCream(flavor,topping,scoops); System.out.println(iceCream); System.out.println("Ice Cream price: "+Currency.formatCurrency(iceCream.getPrice())); totalPrice+=iceCream.getPrice(); break; case 3: Cone cone1 = getConeChoice(); Flavor flavor1 = getFlavorChoice(); Topping topping1 = getToppingChoice(); int scoops1 = getScoopsChoice(); IceCream iceCream1 = new IceCream(flavor1,topping1,scoops1); IceCreamCone iceCreamCone = new IceCreamCone(iceCream1,cone1); System.out.println("IceCream Cone price: "+Currency.formatCurrency(iceCreamCone.getPrice())); System.out.println(iceCream1); totalPrice+=iceCreamCone.getPrice(); break; case 0: break; default: System.err.println("ERROR !!!! .......... wrong choice..Try again!"); break; } if(choice==0) break; } System.out.println("Your total Bill: "+ Currency.formatCurrency(totalPrice)); System.out.println("Thanks for using this App. "); } public static void menu() { System.out.println("1. Cone\n2. Ice Cream \n3. IceCream Cone\n0. Exit\n"); } public static Flavor getFlavorChoice() { System.out.println(Flavors.getFlavors().listFlavors()); int index = Keyboard.getKeyboard().readInt("Select flavour: "); return Flavors.getFlavors().getFlavor(index); } public static Topping getToppingChoice() { System.out.println(Toppings.getToppings().listToppings()); int index = Keyboard.getKeyboard().readInt("Select topping: "); return Toppings.getToppings().getTopping(index); } public static int getScoopsChoice() { int scoops = Keyboard.getKeyboard().readInt("How many scoops do you want: "); return scoops; } public static Cone getConeChoice() { System.out.println("1.Sugar Cone\n2.Waffle cone\n3.Cup\n"); int choice = Keyboard.getKeyboard().readInt("Enter your choice: "); return new Cone(choice); } }
//Output
//If you need any help regarding this solution ......... please leave a comment ........ thanks