Formatting my currency output in toString - java

My code is working fine except for that the formatting is wrong. For example it is outputting:
Teriyaki $0.25 when I need it to output Teriyaki $.25. The only things outputting wrong are with the 0 in front of the decimal. the rest is correct. How can I fix this? Here is my code:
import java.text.NumberFormat;
public class MenuItem
{
private String name;
private double price;
public MenuItem (String name, double price)
{
this.name = name;
this.price = price;
}
public String getName()
{
return name;
}
public double getPrice()
{
return price;
}
public String toString()
{
return (getName() + " " + NumberFormat.getCurrencyInstance().format(getPrice()));
}
}
The test code is:
import java.util.Scanner;
import java.util.Vector;
public class sol
{
public static void main(String[] args)
{
/* Read from keyboard */
Scanner keys = new Scanner(System.in);
/* Create dynamic list */
Vector<MenuItem> list = new Vector<MenuItem>();
/* While there is input waiting */
while (keys.hasNext())
{
/* Prompt the user */
System.out.println("Enter product name and price");
/* Test the constructor */
list.add(new MenuItem(keys.next(), keys.nextDouble()));
}
/* Test toString (implicitly called when passed to println) */
System.out.println("Testing toString");
for (MenuItem mi : list)
System.out.println(mi);
/* Test getters */
System.out.println("Testing getters");
for (MenuItem mi : list)
System.out.println("Item: " + mi.getName() + " Price: " + mi.getPrice());
/* Close keyboard stream */
keys.close();
}
}
Thank you

Create a DecimalFormat to structure decimal numbers how you want them to appear
DecimalFormat twoDForm = new DecimalFormat("#.00");
Double d = Double.parseDouble("0.25");
String s = twoDForm.format(d);
System.out.println(s);
The # in the format indicates:
Digit, zero shows as absent
which will output .25 but still show a leading number if it is non zero

Related

How to create an inventory, add each sale in a dynamic array and calculate total income

I'm new in Java and I have to create an inventory program. The program is:
"A salesman enters his sales in a text file. Every line contains the following (separated by a semicolon; ):
Name of customer (only letters and spaces allowed)
Device sold (smartphone, tablet or laptop)
price (like this ####,##)
date of sale (dd/mm/yy ex. 21/03/21)
Then create a program that does the following:
-Reads from the user the name of the file and opens it. Use the proper exception for the case of the file not existing and ask the user to enter the name of the file again
-Create a class named "Sale" which can store in each of its objects a sale (name, device, price and date, like above). For the device type use ENUM, for the date create a class named "LocalDate"
-Reads the data from the text file and puts them in a dynamic array of 'Sale' objects
-Calculates and prints the total income from the sales for each device type
"
So far I have this:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
import java.util.ArrayList;
public class Files {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("What is the filename?");
String input = in.nextLine();
File file = new File(input);
if(file.exists()){
System.out.println("The file exists. ");
}else {
File file2;
do {
System.out.println("That file does not exist. Please enter the name again. ");
Scanner in2 = new Scanner(System.in);
String input2 = in2.nextLine();
file2 = new File(input2);
if (file2.exists()) {
System.out.println("The file exists. ");
}
} while (!file.exists() && !file2.exists());
}
ArrayList<String> sales = new ArrayList<>();
try(BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\Katerina Efstathiou\\Desktop\\JAVA (1) - Files and exceptions\\javaprogrone.txt"))){
String line;
while ((line = br.readLine()) != null)
//Add the line to the array-list:
sales.add(line);
}catch(IOException e){
e.printStackTrace();
}
int listSize = sales.size(); //variable with the size of the list 'sales'
String[] listOfPrices = new String[listSize]; //define an array of the size of the list
}
}
The 'Sale' class:
public class Sale {
private String customerName; //variables are declared as private
//enum class DeviceType - (enum classes represent a group of constants, like final variables)
//Enum is short for "enumerations", which means "specifically listed"
enum DeviceType{
SMARTPHONE,
TABLET,
LAPTOP
}
private double price; //variables are declared as private
public Sale(String firstName, String lastName){ //constructor of Sale class
customerName = firstName+" "+lastName;
price = 0.0;
}
//subclass LocalDate is static ,so I can access it without creating an object of the Sale class
static class LocalDate{
private int Day;
private int Month;
private int Year;
LocalDate(){
Day=0;
Month=0;
Year=0;
}
public void Date(){
System.out.println(Day+"/"+Month+"/"+Year);
}
}
}
And this is the file that I made:
file of sales
So my issue is how to add each object in an array and how do I calculate the income from the sales for each device? (Meaning if I sold 4 smartphones, how much is the total income for these 4 smartphones?).
I'm really desperate...I don't know what else to do and I really need help...
Understanding that you're learning Java, I've tried to be as simple as possible and have updated your code and pointed out the mistakes.
Let's move step by step.
1: Segregating components
DeviceType enum and LocalDate class
public enum DeviceType {
SMARTPHONE,
TABLET,
LAPTOP;
}
public class LocalDate {
private int day;
private int month;
private int year;
public static LocalDate date(String date) {
final String[] path = date.split("/");
final LocalDate result = new LocalDate();
result.day = Integer.parseInt(path[0]);
result.month = Integer.parseInt(path[1]);
result.year = Integer.parseInt(path[2]);
return result;
}
}
Notice how I've made seperate enum for DeviceType (instead of a sub-enum).
In our Sale class we will just use hasA relationship for the above components.
Also, in the date method, I've updated the logic where you can return an instance of LocalDate class based on your input.
2: Using components
public class Sale {
private final String customerName;
private final double price;
private final DeviceType deviceType;
private final LocalDate date;
public Sale(String firstName, String lastName, final String device, final String cost, final String date) { //constructor of Sale class
customerName = firstName + " " + lastName;
price = Double.parseDouble(cost);
deviceType = DeviceType.valueOf(device);
this.date = LocalDate.date(date);
}
public DeviceType getDeviceType() {
return deviceType;
}
public double getPrice() {
return price;
}
public LocalDate getDate() {
return date;
}
public String getCustomerName() {
return customerName;
}
}
In this step, we construct our Sale class using the inputs provided to us.
We will make use of the components we created above.
3: Getting result
List<Sale> sales = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(file.getAbsolutePath()))) {
String line;
while ((line = br.readLine()) != null) {
//Add the line to the array-list:
final String[] parts = line.split(";");
final String[] cost = parts[2].split(",");
final String[] names = parts[0].split(" ");
final String firstName = names[0].trim();
final String lastName = names[1].trim();
final String costInteger = cost[0].trim();
final String costDecimal = cost[1].trim();
final String device = parts[1].trim();
final String date = parts[3].trim();
final Sale sale = new Sale(firstName, lastName, device, costInteger + "." + costDecimal, date);
sales.add(sale);
}
} catch (IOException e) {
e.printStackTrace();
}
final DeviceType[] deviceTypes = DeviceType.values();
for (final DeviceType deviceType : deviceTypes) {
double sum = 0;
for (final Sale sale : sales) {
if (sale.getDeviceType().name().equals(deviceType.name())) {
sum += sale.getPrice();
}
}
System.out.println("Income for device " + deviceType.name() + " is " + sum);
}
instead of creating ArrayList sales = new ArrayList<>(); we should create a List of Sale
and also for reading the name of file use the file object you created above in your code.
Once, we all things set-up we will just try to find the sum for all the available DeviceType present in the sales list.
First of all you have to modify constructor, it should takes arguments if we want to create objects and add them to list base on file data, it should look like this:
public Sale(String name, double price){ //constructor of Sale class
customerName = name;
this.price = price;
}
Then the main method should looks like:
public class Files {
public static void main(String[] args) {
ArrayList<String> sales = new ArrayList<>();
try(BufferedReader br = new BufferedReader(new FileReader(/*here put your file path"/Users/aabdelaziz/Desktop/f.txt"))){
String line;
while ((line = br.readLine()) != null)
//Add the line to the array-list:
sales.add(line);
}catch(IOException e){
e.printStackTrace();
}
ArrayList<Sale> listOfSales = new ArrayList<>();
//add sales objects from file to list of sales
for (String s: sales){
String[] saleProperties = s.split(";");
//switch the comma in price number by dot
String[] splitPrice = saleProperties[2].split(",");
double price = Double.parseDouble(splitPrice[0] + "." + splitPrice[1]);
Sale sale = new Sale(saleProperties[0].trim(), price);
listOfSales.add(sale);
}
//calculate total prices
double totalPrices = 0;
for (Sale sale: listOfSales){
//you have to add getPrice Method in Sale class
totalPrices += sale.getPrice();
}
System.out.println(totalPrices);
}
}
//if you interested in date and device type you can add them in constructorenter code here

Java - Printing ArrayList objects in specific format through toString() method

I'm making a solar system model that uses takes different solar systems and sets of planets through the use of classes. I've chosen to use an arraylist to store each object of a planet within the solar system although am now struggling to output the data in a suitable format.
The format i am looking for in the toString() method is 'Planet X has a mass of A Earths, is BAU from its star, and orbits in C years: could be habitable? D'
I have attempted using for loops to print each planet however don't believe this is the correct way as a return will cause the loop to stop. Many thanks
SolarSystem.java
import java.util.ArrayList;
public class SolarSystem {
private String systemName;
private double systemLuminosity;
public SolarSystem(String name, double luminosity) {
this.systemName = name;
this.systemLuminosity = luminosity;
}
ArrayList<Planet> list = new ArrayList<>();
public void addPlanet(String name, double mass, double distance) {
list.add(new Planet(name, mass, distance, systemLuminosity));
}
public void planetProperties() {
}
public String toString() {
System.out.println(list.size());
String results = "+";
for (Planet planet : list) {
results += planet.getName(); //if you implement toString() for Dog then it will be added here
}
return results;
}
}
Planet.java
public class Planet {
private String planetName;
private double planetMass;
private double distanceFromStar;
private double orbitalPeriod;
private String isHabitable;
public Planet(String name, double mass, double distance, double systemLuminosity) {
setName(name);
setMass(mass);
setDistanceFromSun(distance);
setOrbitalPeriod(distance);
setIsHabitable(mass, distance, systemLuminosity);
}
public void setName(String name) {
planetName = name;
}
public String getName() {
return planetName;
}
public void setMass(double mass) {
planetMass = mass;
}
public double getMass() {
return planetMass;
}
public void setDistanceFromSun(double distance) {
distanceFromStar = distance;
}
public double getDistanceFromStar() {
return distanceFromStar;
}
public void setOrbitalPeriod(double distance) {
orbitalPeriod = Math.sqrt(distance*distance*distance);
}
public double getOrbitalPeriod() {
return orbitalPeriod;
}
public void setIsHabitable(double mass, double distance, double luminosity) {
if (mass >= 0.6 && mass <= 7.0) {
if ((distance >= 0.75 * Math.sqrt(luminosity)) && (distance <= 2.0 * Math.sqrt(luminosity))) {
isHabitable = "yes";
} else {
isHabitable = "no";
}
} else {
isHabitable = "no";
}
}
public String getIsHabitable() {
return isHabitable;
}
}
Main.java
public class Main {
public static void main(String[] args) {
//Create our solar system
SolarSystem ourSystem = new SolarSystem("Our System",1.0);
//Add planets in our solar system
ourSystem.addPlanet("Mercury", 0.055, 0.387);
ourSystem.addPlanet("Venus", 0.815, 0.723);
ourSystem.addPlanet("Earth", 1.0, 1.0);
ourSystem.addPlanet("Mars", 0.107, 1.52);
ourSystem.addPlanet("Jupiter", 317.8, 5.20);
ourSystem.addPlanet("Saturn", 95.2, 9.58);
ourSystem.addPlanet("Uranus", 14.5, 19.20);
ourSystem.addPlanet("Neptune", 17.1, 30.05);
System.out.println(ourSystem.toString());
}
}
You need to implement a toString() method inside your Planet class, for example:
class Planet {
private String planetName;
private double planetMass;
private double distanceFromStar;
private double orbitalPeriod;
private String isHabitable;
#Override
public String toString() {
return String.format(
"Planet %s has a mass of %f Earths, is %f from its star, and orbits in %f years: could be habitable? %s%n",
this.planetName, this.planetMass, this.distanceFromStar, this.orbitalPeriod, this.isHabitable);
}
}
Then inside your SolarSystem class you can create a list with something like this, you already have that part almost correct but I've changed getName to toString:
#Override
public String toString() {
StringBuilder buf = new StringBuilder();
for (Planet planet : list) {
buf.append(planet);
}
return buf.toString();
}
If you want to print out a description for the entire solar system (the entire array list of planets), I would suggest to implement the toString() method inside the Planet class. Doing so will allow you to simply iterate over the Planets array list, and just call planet.toString(). Encapsulating the logic for a singular planet inside the Planet class is the way to go.
You have to redefine toString in the Planet class and replace the toString of SolarSystem to use it.
public class Planet {
...
public String toString() {
return "Planet " + planetName + " has a mass of " + planetMass +
" Earths, is BAU from its star, and orbits in " + orbitalPeriod +
" years: could be habitable? " + isHabitable;
}
}
public class SolarSystem {
...
public String toString() {
String results = "";
for (Planet planet : list) {
results += planet.toString() + "\n"; // Use the toString of planet and add a new line
}
return results;
}
}
Note: for performance reasons as commented by oleg it is preferable to use a StringBuilder to concatenate strings. In this situation where you have few items and the problem is not related to the performances you can leave the + operator.
Growing your java knowledge you will find useful functions like String.join:
Returns a new String composed of copies of the CharSequence elements joined together with a copy of the specified delimiter.
That will help you mantaining your code simpler and cleaner replacing this:
public String toString() {
String results = "";
for (Planet planet : list) {
results += planet.toString() + "\n"; // Use the toString of planet and add a new line
}
return results;
}
with
public String toString() {
return String.join("\n", list);
}
but my tip is to start from the basis of java before trying to use more advanced functions. Otherwise you will use them without knowing what happens behind the scenes
To echo other posters, you need to define a custom toString() method in the planet class first. Please see my suggestions below. They are presented as pseudo-code typed on the fly, not actual code (for there might be a few things here and there that might not compile.)
But the pseudo-code should give an idea for a possible solution. Hit me up if you still have questions.
Based on your requirements:
The format i am looking for in the toString() method is 'Planet X has
a mass of A Earths, is BAU from its star, and orbits in C years: could
be habitable? D'
Your Planet.toString method could look as follows (this is pseudo-code, not bound to be compilable, but you get the gist of it.)
public class Planet {
/* your class as it is, with the
* addition of a possible toString
* implementation */
public String toString(){
return String.format(
"Planet: %s, " +
"mass: %f, " +
"distance: %f, " +
"orbital period: %f, " +
"habitable: %b"
this.getName(),
this.getMass(),
this.getDistanceFromStar(),
this.getOrbitalPeriod(),
this.getIsHabitable());
}
}
Then, your SolarSystem class should have an appropriate toString method that loops over the collection of planets in it. Your original toString method had the right idea, I'm just extending the notion.
public class SolarSystem {
/*
Your solar system class plus some changes
...
*/
public String getName(){
return this.systemName;
}
public String getLuminosity(){
return this.systemLuminosity;
}
public int getPlanetCount(){
return this.list.size();
}
public String toString() {
final StringBuffer buffer = new StringBuffer();
buffer.append(
String.format("System: %s\nLuminosity: %f\nPlanet Count:%d\n",
this.getName(),
this.getLuminosity(),
this.getPlanetCount()
)
);
for (final Planet planet : list) {
buffer.append('\t')
.append(planet.getString())
.append('\n');
}
return buffer.toString();
}
}
Now, I'm a bit confused with this:
I have attempted using for loops to print each planet however don't
believe this is the correct way as a return will cause the loop to
stop. Many thanks
A return statement will stop a loop if the return is done within the loop.
A return statement done within a function called within the loop will not end the loop.
That is, a return only ends the function that makes the return call, not functions up in the call chain.
Compare this
for(Foo f : fooList){
if(something){
return; // this will stop the loop
}
}
With this
for(Foo f : fooList){
if(something){
callThisFu(); // the return within callThisFu *will not* exit the loop
}
}
Hope this clear this up.

Printing Java ArrayList<Object> Dilemma [duplicate]

This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 7 years ago.
Recently, I've learned something: I have no idea how to use toString methods.(If you've seen my last question, you'll get a prime example.)
Anyways, I was going through some unfinished programs of mine from an Intro to Java class I took last year and this one I just cannot finish. My effort to become a better programmer has faced the ultimate challenge: toString methods.
The basic overview is that I had to write a 'Grocery' store program where the ShoppingCart class was an ArrayList of Grocery Objects.
There's just one problem- when I run the program I get
Grocery.ShoppingCart#2eeb3c84
My old enemy, the toString() looks like it is required.
The output I should be getting is this:
[Tomatoes: 2.76 $1.39, Mac & Cheese: 6.0, $0.89]
now if I print out the Cart ArrayList (System.out.println(Cart)) I get this:
[Tomatoes, 2.76, $1.39, Mac & Cheese, 6.0, $0.89]
Exactly the output I should be getting.
How does this happen? How can I fix this?
When I print out the Cart Arraylist, I get the output I want (I still get the "Grocery.ShoppingCart#). I have to find some way to replace the "Grocery.ShoppingCart#[etc.]" with the ArrayList.
Anybody have any ideas?
Thanks!
-Chris
Bits of the ShoppingCart class:
ArrayList<Grocery> Cart = new ArrayList<Grocery>();
int size = Cart.size();
double tot = 0.0;
public ShoppingCart(){
}
...
public void printReceipt() {
Grocery temp = new Grocery();
double pr = 0.0;
double qu = 0.0;
String n = "";
String con = "IF YOU SEE ME SOMETHING IS WRONG!";
double gr = 0.0;
for(int k = 0; k < size; k++){
temp = Cart.get(k);
n = temp.getName();
qu = temp.getQuan();
pr = temp.getPrice();
tot = qu * pr;
con = n + ":" + " " + qu + ", " + pr + "\t\t Total: $" + tot;
}
System.out.println("====RECIEPT====");
System.out.println("Grand Total:\t" + "$" + totalPr());
}
Grocery Class Printing out ShoppingCart
public static void testShoppingCartClass ()
{
System.out.println ("Testing ShoppingCart class\n");
ShoppingCart myCart = new ShoppingCart();
System.out.println (" ShoppingCart using default constructor: ");
System.out.println ("\t" + myCart);
myCart.addItem (new Grocery("Tomatoes", 2.76, 1.39));
myCart.addItem (new Grocery("Mozzarella", 0.95, 4.59));
myCart.addItem (new Grocery("Mac & Cheese", 6, 0.89));
System.out.println ("\n ShoppingCart after adding three items: ");
System.out.println ("\t" + myCart);
myCart.removeItem (1);
System.out.println ("\n ShoppingCart after removing an item: ");
System.out.println ("\t" + myCart);
System.out.println ("\n\nPrinting receipt: \n");
myCart.printReceipt();
System.out.println ("\n\nDone testing ShoppingCart class\n\n");
}
You can override toString to return whatever you want. In your case, it looks like you want to do:
class ShoppingCart {
ArrayList<Grocery> cart;
...
#Override
public String toString() {
return cart.toString();
}
}
Java's default toString() method on any object will print out what you're seeing ("Grocery.ShoppingCart#[etc.]"). This is the Class with the object's hash code appended to the end of it.
From what I see in that output, you're calling .toString() on an instance of the ShoppingCart class which is why you're getting that output.
In order for that class to print out the contents of the ArrayList - Cart, which is a member of that class, you will need to override the toString() method of that class to print the contents of the ArrayList. Once it is overridden, your implementation of the toString() will be called rather than the default.
public String toString() {
// return the string that you want.
}
toString() is called on shoppingCart when you call System.out.println(shoppingCart) in order to retrieve the string to print.
Yes, you'll need a toString() on your ShoppingCart.
If I understand what you're trying to do though, may I suggest going with a more conventional Java bean approach? Here's a simplistic view.
Bean with getter and setters. A better name for this might be Item. You can change the types as needed as well.
public class Grocery {
public BigDecimal getQuantity() {
return quantity;
}
public void setQuantity(BigDecimal quantity) {
this.quantity = quantity;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private BigDecimal quantity;
private BigDecimal price;
private String name;
#Override
public String toString() {
return "Grocery{" +
"quantity=" + quantity +
", price=" + price +
", name='" + name + '\'' +
'}';
}
}
And your cart:
public class ShoppingCart {
List<Grocery> contents;
public void initialize() {
contents = new ArrayList<Grocery>();
}
public void addItem(Grocery item) {
contents.add(item);
}
public void removeItem(Grocery item) {
boolean wasRemoved = contents.remove(item);
if (!wasRemoved) {
System.out.println("Item not found in cart: " + item);
}
}
public List<Grocery> getContents() {
return contents;
}
#Override
public String toString() {
return "ShoppingCart{" +
"contents=" + contents +
'}';
}
}
And some class to run it:
public class CartRun {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
cart.initialize();
Grocery item = new Grocery();
item.setName("Tomatoes");
item.setPrice(BigDecimal.valueOf(2));
item.setQuantity(BigDecimal.valueOf(3));
cart.addItem(item);
System.out.println("Item="+item);
System.out.println("Cart="+cart);
}
}
Output:
Item=Grocery{quantity=3, price=2, name='Tomatoes'}
Cart=ShoppingCart{contents=[Grocery{quantity=3, price=2, name='Tomatoes'}]}
Also, stay away from capital letters (e.g., "Cart") for variable names because it looks like a static method call by convention.

How to turn main method class to Junit test class?

I wrote a small project named Sales Taxes on Intellij IDEA. To run the program, I included a main method. Now I need to write JUnit tests for the project. I do not have much experience about writing test classes. How can I turn my main method to Junit test class?
Here is the project that I constructed:
Basic sales tax is applicable at a rate of 10% on all goods, except books, food, and medical products that are exempt.
Import duty is an additional sales tax applicable on all imported goods at a rate of 5%, with no exemptions.
When I purchase items I receive a receipt which lists the name of all the items and their price (including tax), finishing
with the total cost of the items, and the total amounts of sales taxes paid. The rounding rules for sales tax are that for
a tax rate of n%, a shelf price of p contains (np/100 rounded up to the nearest 0.05) amount of sales tax.
Write an application that prints out the receipt details for these shopping baskets...
Product.java
/*
Definition of Product.java class
Fundamental object for the project.
It keeps all features of the product.
At description of the product, description of the input line for output line.
typeOfProduct: 0:other 1:food 2:book 3: medical products
*/
public class Product{
private int typeOfProduct=0;
private boolean imported=false;
private double price=0;
private double priceWithTaxes=0;
private double taxes=0;
private int quantity=0;
private String description="";
public Product(int quantity, int typeOfProduct, boolean imported, double price, String description)
{
this.quantity=quantity;
this.typeOfProduct = typeOfProduct;
this.imported = imported;
this.price = price;
this.description = description;
}
public void setTypeOfProduct(int typeOfProduct)
{
this.typeOfProduct = typeOfProduct;
}
public int getTypeOfProduct()
{
return typeOfProduct;
}
public void setImported(boolean imported)
{
this.imported = imported;
}
public boolean getImported()
{
return imported;
}
public void setPrice(double price)
{
this.price = price;
}
public double getPrice()
{
return price;
}
public void setTaxes(double taxes)
{
this.taxes = taxes;
}
public double getTaxes()
{
return taxes;
}
public void setPriceWithTaxes(double priceWithTaxes)
{
this.priceWithTaxes = priceWithTaxes;
}
public double getPriceWithTaxes()
{
return priceWithTaxes;
}
public void setQuantity(int quantity)
{
this.quantity = quantity;
}
public int getQuantity()
{
return quantity;
}
public void setDescription(String description)
{
this.description = description;
}
public String getDescription()
{
return description;
}
}
TaxCalculator.java
/*
Definition of TaxCalculator.java class
At constructor a Product object is taken.
taxCalculate method; adds necessary taxes to price of product.
Tax rules:
1. if the product is imported, tax %5 of price
2. if the product is not food, book or medical goods, tax %10 of price
typeOfProduct: 0:food 1:book 2: medical products 3:other
*/
public class TaxCalculator {
private Product product=null;
public TaxCalculator(Product product)
{
this.product=product;
}
public void taxCalculate()
{
double price=product.getPrice();
double tax=0;
//check impoted or not
if(product.getImported())
{
tax+= price*5/100;
}
//check type of product
if(product.getTypeOfProduct()==3)
{
tax+= price/10;
}
product.setTaxes(Util.roundDouble(tax));
product.setPriceWithTaxes(Util.roundDouble(tax)+price);
}
}
Util.java
import java.text.DecimalFormat;
/*
Definition of Util.java class
It rounds and formats the price and taxes.
Round rules for sales taxes: rounded up to the nearest 0.05
Format: 0.00
*/
public class Util {
public static String round(double value)
{
double rounded = (double) Math.round(value * 100)/ 100;
DecimalFormat df=new DecimalFormat("0.00");
rounded = Double.valueOf(df.format(rounded));
return df.format(rounded).toString();
}
public static double roundDouble(double value)
{
double rounded = (double) Math.round(value * 20)/ 20;
if(rounded<value)
{
rounded = (double) Math.round((value+0.05) * 20)/ 20;
}
return rounded;
}
public static String roundTax(double value)
{
double rounded = (double) Math.round(value * 20)/ 20;
if(rounded<value)
{
rounded = (double) Math.round((value+0.05) * 20)/ 20;
}
DecimalFormat df=new DecimalFormat("0.00");
rounded = Double.valueOf(df.format(rounded));
return df.format(rounded).toString();
}
}
SalesManager.java
import java.util.ArrayList;
import java.util.StringTokenizer;
/*
Definition of SalesManager.java class
This class asks to taxes to TaxCalculator Class and creates Product objects.
*/
public class SalesManager {
private String [][] arTypeOfProduct = new String [][]{
{"CHOCOLATE", "CHOCOLATES", "BREAD", "BREADS", "WATER", "COLA", "EGG", "EGGS"},
{"BOOK", "BOOKS"},
{"PILL", "PILLS", "SYRUP", "SYRUPS"}
};
/*
* It takes all inputs as ArrayList, and returns output as ArrayList
* Difference between output and input arrayLists are Total price and Sales Takes.
*/
public ArrayList<String> inputs(ArrayList<String> items)
{
Product product=null;
double salesTaxes=0;
double total=0;
TaxCalculator tax=null;
ArrayList<String> output=new ArrayList<String>();
for(int i=0; i<items.size(); i++)
{
product= parse(items.get(i));
tax=new TaxCalculator(product);
tax.taxCalculate();
salesTaxes+=product.getTaxes();
total+=product.getPriceWithTaxes();
output.add(""+product.getDescription()+" "+Util.round(product.getPriceWithTaxes()));
}
output.add("Sales Taxes: "+Util.round(salesTaxes));
output.add("Total: "+Util.round(total));
return output;
}
/*
* The method takes all line and create product object.
* To create the object, it analyses all line.
* "1 chocolate bar at 0.85"
* First word is quantity
* Last word is price
* between those words, to analyse it checks all words
*/
public Product parse(String line)
{
Product product=null;
String productName="";
int typeOfProduct=0;
boolean imported=false;
double price=0;
int quantity=0;
String description="";
ArrayList<String> wordsOfInput = new ArrayList<String>();
StringTokenizer st = new StringTokenizer(line, " ");
String tmpWord="";
while (st.hasMoreTokens())
{
tmpWord=st.nextToken();
wordsOfInput.add(tmpWord);
}
quantity=Integer.parseInt(wordsOfInput.get(0));
imported = searchImported(wordsOfInput);
typeOfProduct = searchTypeOfProduct(wordsOfInput);
price=Double.parseDouble(wordsOfInput.get(wordsOfInput.size()-1));
description=wordsOfInput.get(0);
for(int i=1; i<wordsOfInput.size()-2; i++)
{
description=description.concat(" ");
description=description.concat(wordsOfInput.get(i));
}
description=description.concat(":");
product=new Product(quantity, typeOfProduct, imported, price, description);
return product;
}
/*
* It checks all line to find "imported" word, and returns boolean as imported or not.
*/
public boolean searchImported(ArrayList<String> wordsOfInput)
{
boolean result =false;
for(int i=0; i<wordsOfInput.size(); i++)
{
if(wordsOfInput.get(i).equalsIgnoreCase("imported"))
{
return true;
}
}
return result;
}
//typeOfProduct: 0:food 1:book 2: medical goods 3:other
/*
* It checks all 2D array to find the typeOf product
* i=0 : Food
* i=1 : Book
* i=2 : Medical goods
*/
public int searchTypeOfProduct (ArrayList<String> line)
{
int result=3;
for(int k=1; k<line.size()-2; k++)
{
for(int i=0; i<arTypeOfProduct.length; i++)
{
for(int j=0; j<arTypeOfProduct[i].length; j++)
{
if(line.get(k).equalsIgnoreCase(arTypeOfProduct[i][j]))
{
return i;
}
}
}
}
return result;
}
}
SalesTaxes.java
import java.io.IOException;
import java.util.ArrayList;
public class SalesTaxes {
public static void main(String args[]) throws IOException
{
ArrayList<String> input = new ArrayList<String>();
ArrayList<String> output = new ArrayList<String>();
SalesManager sal = new SalesManager();
/*
* First input set
*/
System.out.println("First input Set");
System.out.println();
input = new ArrayList<String>();
input.add("1 book at 12.49");
input.add("1 music CD at 14.99");
input.add("1 chocolate bar at 0.85");
sal=new SalesManager();
output= sal.inputs(input);
for(int i=0; i<output.size(); i++)
{
System.out.println(output.get(i));
}
/*
* Second input set
*/
System.out.println();
System.out.println("Second input Set");
System.out.println();
input = new ArrayList<String>();
input.add("1 imported box of chocolates at 10.00");
input.add("1 imported bottle of perfume at 47.50");
sal=new SalesManager();
output= sal.inputs(input);
for(int i=0; i<output.size(); i++)
{
System.out.println(output.get(i));
}
/*
* Third input set
*/
System.out.println();
System.out.println("Third input Set");
System.out.println();
input = new ArrayList<String>();
input.add("1 imported bottle of perfume at 27.99");
input.add("1 bottle of perfume at 18.99");
input.add("1 packet of headache pills at 9.75");
input.add("1 box of imported chocolates at 11.25");
output= sal.inputs(input);
for(int i=0; i<output.size(); i++)
{
System.out.println(output.get(i));
}
}
}
I think that you can start with searching about how to write unit tests, maybe than you will not have this kind of question. The main point there is to test some piece of functionality. For example, in your case you should test taxCalculate method and check if in your product the tax was set correctly, probably you will need a getter for a product in this case.
Also, check this: how to write a unit test.
A "unit test" is for one class.
So I wouldn't start with the main method: that wouldn't give you "unit tests". That would give you an "integration test" (testing a bunch of your classes all at once).
So, for unit tests, I would start by writing a UtilTest class to test just your Util class. That has public methods that can easily be given different inputs and the results asserted. e.g. what do you get back if you give roundTax zero, or 21.0, etc.?

How can I get an ArrayList to print out information of different data types?

I have an assignment where I have to print US states by order of the highest to lowest percentage of eligible citizens enrolled in the Affordable Healthcare Act. I had to create an ArrayList and it holds two different types of data: two Strings and 3 doubles. I am very close to completion but I have been stumped at:
How do I print out the states line by line? I think I should use t/ to start a new line.
How do I print out the states in order of highest to lowest percentages?
Code so far.
import java.util.*;
import java.io.*;
import java.util.ArrayList;
// Calculates the percentage of citizens enrolled in the Affordable Healthcare Act
// Lists the states in order of highest percentage of enrolled citizens in the Affordable Healthcare Act
public class ACA {
public static void main( String[] args ) throws FileNotFoundException {
Scanner keyboard = new Scanner(System.in); // creates an object of the Scanner class
System.out.println("Enter filename"); // prompts the user for the name of the file
String filename = keyboard.next(); // the user response is stored
File inputFile = new File(filename+".txt"); // takes the filename and creates an object of the File class
Scanner fileIn = new Scanner(inputFile); // takes the object and converts the file to an obect of the Scanner class to allow it to be read
// creates an object of the ArrayList class
ArrayList<ACAdata> info = new ArrayList<>();
// variables declared for each column of data in the line
String state = " "; // State abbreviation
String org = " "; // Organizer of the ACA marketplace, either FFM for federally facilitated marketplace or SBM for state based marketplace.
double numEll = 0; // Number of citizens in the state eligible for ACA coverage
double numEn = 0; // Number of citizens who enrolled in an ACA plan
// while loop will evaluate as long as there are rows of data in the text file
while ( fileIn.hasNext() ) {
state = fileIn.next(); // individual state
org = fileIn.next(); // organization
numEll = fileIn.nextDouble(); // number of elligible citizens for that state for the Affordable Healthcare Act
numEn = fileIn.nextDouble(); // number of citizens enrolled in the Affordable Healthcare Act
double percentage = per( numEll, numEn ); // calls the per method to calculate a percentage for each state
// adds the 5 fields of data to a new ArrayList that holds the information for each state
info.add(new ACAdata( state, org, numEll, numEn, percentage));
}
// Prints out the information about the state
for ( int i = 0; i < info.size(); i++ ) {
System.out.println((info.get(i)).toString());
}
}
// method that finds the percentage of enrolled citizens that are elligible for the Affordable Care Act
public static double per( double Ell, double En ) {
double calculation = En / Ell * 100; // divides the Enrolled by the number of elligible citizens
return calculation; // returns the calculation
}
}
public class ACAdata {
// variables declared for each column of data in the line
String state = " "; // State abbreviation
String org = " "; // Organizer of the ACA marketplace, either FFM for federally facilitated marketplace or SBM for state based marketplace.
double numEll = 0; // Number of citizens in the state eligible for ACA coverage
double numEn = 0; // Number of citizens who enrolled in an ACA plan
double percentage = 0;
public ACAdata ( String state, String org, double numEll, double numEn, double percentage ) {
state = state;
org = org;
numEll = numEll;
numEn = numEn;
percentage = percentage;
}
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
}
public String getOrg() {
return this.org;
}
public void setOrg( String org ) {
this.org = org;
}
public double getNumEll() {
return this.numEll;
}
public void setNumEll( double numEll ) {
this.numEll = numEll;
}
public double getNumEn( double numEn ) {
return this.numEn;
}
public double getPercentage() {
return this.percentage;
}
public void setPercentage( double percentage ) {
this.percentage = percentage;
}
}
To make the ACAdata Object sortable.
If you have this Object you can sort it and then output it with.
ArrayList<ACAdata> list = new ArrayList<>();
Collections.sort(list);
for (Iterator<ACAdata> iterator = list.iterator(); iterator.hasNext();) {
ACAdata next = iterator.next();
System.out.println(next.toString());
}
public class ACAdata implements Comparable<ACAdata> {
// variables declared for each column of data in the line
String state = " "; // State abbreviation
String org = " "; // Organizer of the ACA marketplace, either FFM for federally facilitated marketplace or SBM for state based marketplace.
double numEll = 0; // Number of citizens in the state eligible for ACA coverage
double numEn = 0; // Number of citizens who enrolled in an ACA plan
double percentage = 0;
public ACAdata(String state, String org, double numEll, double numEn, double percentage) {
state = state;
org = org;
numEll = numEll;
numEn = numEn;
percentage = percentage;
}
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
}
public String getOrg() {
return this.org;
}
public void setOrg(String org) {
this.org = org;
}
public double getNumEll() {
return this.numEll;
}
public void setNumEll(double numEll) {
this.numEll = numEll;
}
public double getNumEn(double numEn) {
return this.numEn;
}
public double getPercentage() {
return this.percentage;
}
public void setPercentage(double percentage) {
this.percentage = percentage;
}
#Override
public int compareTo(ACAdata o) {
if (percentage > o.percentage) {
return -1;
}
if (percentage < o.percentage) {
return 1;
}
return 0;
}
#Override
public String toString() {
return "Put the info you want here!";
}
}
Looking at your code, the easiest solution (that I can think of) is to override toString in ACAdata with something like (add and format it how you want it)
#Override
public String toString() {
return String.format("%s %s %.2f %.2f", state, org, numEll, numEn);
}
And then you can just print the entire ArrayList, or individual ACAdata instances. You're already calling toString(), but you don't have to... Java will implicitly make a toString() call for you when you try and print an Object (the default implementation in Object just didn't do what you wanted).

Categories

Resources