Search code examples
javamathsuperclass

Calculation incorrect and can't figure out why


I have 3 classes: Order, InternalOrder and OrderTester. I have been searching around for a while and with the things I've been looking at I just haven't been able to try change those examples to what I need here.

So I'm having trouble with the InternalOrder and OrderTester classes. My code so far for both are...

public class InternalOrder extends Order {
   public static final int DISCOUNT = 40/100; 

    public InternalOrder(String productName, int quantity) {
        super(productName, quantity, DISCOUNT);
        }

public void printInternalReport() {
    System.out.println("Printing internal report...");
}

}

And

public class OrderTester {

public static void main(String[] args) {
    testCase1();
    testCase2();
    testCase3();
    testCase4();
    testCase5();
    testCase6();
    testCase7();
    testCase8();
    testCase9();
    testCase10();
}
public static void testCase1() {
    Order ord = new Order();

    System.out.println("Test Number : " + Order.orderNum + " Type of Order : Normal, " +  "Product Name : "  + "Order Quantity : " + "Discount : ");
}
public static void testCase2() {
    Order ord = new Order();

    System.out.println("Test Number : " + Order.orderNum + " Type of Order : Normal, " + "Product Name : "  + "Order Quantity : " + "Discount : ");
}

Well, it goes to test 10 but it's all the same at the moment.

Here are the things I need:

The InternalOrder class is to contain the logic for Stellar Stationary staff who order stationary stock internally as part of their work requirements.

Internal orders automatically receive a 40% discount.

  • The InternalOrder class is to extend the Order class.
  • Is to contain a final static field called DISCOUNT. This field is used as a constant for the discounted rate that staff receive and should be set to 40%.

Now, I have these two in my part, but I'm not fully sure with the next part.

  • The class is to contain one constructor. The constructor is to receive two parameters, productName and quantity. The constructor is to pass these parameters to its superclass (Order) as well as the DISCOUNT constant as a third parameter.

Do I need to have anything added with the superclass, becuase that's quite confusing me. And with the OrderTester, I have a table which is just hard to import so I'll just produce a couple of the lines.

The OrderTester class is used to launch the program and to test the Order and InternalOrder classes to make sure it is working correctly.

There are ten tests to be run and each test should be in a static method of its own and they should be called testCase1() through testCase10(). Each test should test as per the following table:

Test Number  Type of Order  Product Name  Order Quantity  Discount
1           "Normal"       "N/A"           "N/A"        "N/A"

With this test. I'm not sure how I would produce "N/A" when my Quantity and Discount are ints.

If you need my other code, I'll post it below.

    public class Order {

private String productName;
private double price;  
private int discount;  
private int quantity;  
private double total; 
private String message;
private boolean isDiscounted;
private boolean isValidOrder;
public static int orderNum = 0;

      public Order() { 
        isValidOrder = false;
        message = "**ERROR** Order number cannot be totalled as no details have been supplied.";
        orderNum++;
    }

  public Order(String productName, int quantity){  
      this.productName = productName;
      this.quantity = quantity;
      getPrice(this.productName);


      if(isValidOrder != false){
          calculate();
      }
      orderNum++;

  }

public Order(String productName, int quantity, int discount){ 
    this.productName = productName;
    testQuantity(quantity);
    getPrice(productName);

      if(isValidOrder != false){
          calculate();
      }
              orderNum++;
}

private String getOrderDetails(){
    message = message;
    if(isValidOrder == true && isDiscounted == false){

        message = "Order Number: " + quantity + "\n" + "Product Name; " + productName + "\n" + "Product Price: $" + price + "\n" + "Order Quantity: " + quantity + "\n" + "Total Price: $" + total;  

    } else if(isValidOrder == true && isDiscounted == true){

        message = "Order Number: " + quantity + "\n" + "Product Name; " + productName + "\n" + "Product Price: $" + price + "\n" + "Order Quantity: " + quantity + "\n" + "Total Price: $" + total;  
    }  else {
        return message;  
    }
    return message; 
}


private void calculate(){ 

    if(this.isDiscounted == false){
        total = quantity * price;
    } else {
        total = quantity * price - quantity * price * (discount / 100 );  
    }
}

private void getPrice(String productName){ 
    switch(productName){
    case "Pencil":
        this.price = 0.6;
        break;
    case "Pen":
        this.price = 0.3;
        break;
    case "Ruler":
        this.price = 1.2;
                    break;
    case "Pencil Sharpener":
        this.price = 0.3;
        break;
    case "Compass":
        this.price = 4.5;
        break;
    case "Erasor":
        this.price = 4.5;
        break;
    case "Scissors":
        this.price = 2.5;
                    break;
    case "Pencil Case":
        this.price = 10.0;
        break;
    default:
        this.price = 0.0;
        this.isValidOrder = false;
        this.message = "**ERROR**: Invalid product name";
                    break;
            }
}

private void testDiscount(int discount) { 
    if (discount <=0) {
        message = "**ERROR**: The discount rate cannot be lower than or equal to 0.";
    }
    else if (discount >50) {
        message = "**ERROR**: The discount rate cannot be higher than 50.";
    } else {
   this.discount = discount;        
   this.isDiscounted = true;    
    }  
}


private void testQuantity(int quantity){  
       if(quantity <=0) {
            isValidOrder = false;
            message = ("**ERROR**: Invalid quantity. Quantity cannot be 0 or less.");
                message = message + "messagehere";
                message += "messagehere";
    }
        else if (quantity >1000) {
            isValidOrder = false;
            message = ("**ERROR**: Invalid quantity. Quantity cannot be greater than 1000.");
        }  else {
            isValidOrder = true;
            this.quantity = quantity;
        }
}

}

Solution

  • This line could be the source of your bugs:

     public static final int DISCOUNT = 40/100; 
    

    DISCOUNT is zero.

    The reason is the result of the division of two integers is trucated to the nearest lower integer - the decimal places are simply chopped off. Since 40/100 is .4, after the decimal places are removed you're left with 0.

    You have basically two choices:

    Save it as a percentage:

    public static final int DISCOUNT_PERCENT = 40; 
    

    Use a type that can store decimals:

    public static final double DISCOUNT = .4;
    

    Your life will probably be easier if you chose the second option, because if you use an int, anytime you multiply by it you'll face similar arithmetic problems.