Hi there! I've recently been getting into java and was wondering how I can clean up or condense the code for this problem I've been working on The program asks the user to enter values for items bought, the price of each item, the GST rate, the QST rate. The program calculates the subtotal based on these inputs. For every invalid input entered by the user the program will prompt the user to re-enter that value until it is a valid input. Items bought must be between 1 and 10. The price of each item must be between 1 and 1000. The GST must be between 0 and 14. The QST must be between 0 and 17.

Im wondering if there's a way I can make this code more efficient by including more methods or anything else. Thanks!   

import java.util.Scanner;
        public class Taxes{
        public static void main(String[] args){
        double subtotal = 0;
        int errors = 0;
        Scanner scan = new Scanner(System.in);
        System.out.println("Please enter the number of items bought (1-10): ");
        int num_items = scan.nextInt();
        while (num_items &lt; 1 || 10 &lt; num_items){
            errors += 1;
            System.out.println("Please enter the number of items bought (1-10): ");
            num_items = scan.nextInt();
        }

        for (int i = 1; i &lt;= num_items; i++){
            Scanner scn = new Scanner(System.in);
            System.out.println("Please enter the price of item " + i);
            Double item_cost = scn.nextDouble();
            while (item_cost &lt; 1 || 1000 &lt; item_cost){
                errors += 1;
                System.out.println("Please enter the price of item " + i);
                item_cost = scn.nextDouble();
            }
            subtotal += item_cost;
        }
        System.out.println("Please enter the tax rate of GST in %: ");
        double gRate = scan.nextDouble();
        while (gRate &lt; 0 || 14 &lt; gRate){
            errors += 1;
            System.out.println("Please enter the tax rate of GST in %: ");
            gRate = scan.nextDouble();
        }
        System.out.println("Please enter the tax rate of QST in %: ");
        double qRate = scan.nextDouble();

        while (qRate &lt; 0 || 17 &lt; qRate){
            errors += 1;
            System.out.println("Please enter the tax rate of QST in %: ");
            qRate = scan.nextDouble();
        }
        calculate(subtotal, gRate, qRate, errors);
}


    public static void calculate(double subtotal, double gRate, double qRate, int errors)
        {
            double gst = subtotal * (gRate/100); 
            double qst = (subtotal + gst) * (qRate/100);
            double total = subtotal + gst + qst;
            System.out.println("GST: " + gst);
            System.out.println("QST: " + qst);
            System.out.println("Subtotal: "  + total);
            System.out.println("You entered " + errors + " invalid inputs");
        }

    }
Style


Please use proper indentation. It is generally considered good practice to indent the code inside a method. This will make your code more legible.
The use of curly brackets is inconsistent (have a look at the calculate-method. In Java, the most common use of curly brackets looks like this:


public static void calculate(...) {
    //Commands here
}



For variable names the lowerCamelCase is used. So num_items becomes numItems and item_cost becomes itemCost.




Input

You have been thinking about how to stop the user from making invalid inputs. You are using:

while (numItems &lt; 1 || 10 &lt; numItems) {
            errors += 1;
            System.out.println("Please enter the number of items bought (1-10): ");
            numItems = scan.nextInt();
        }


This will stop the user entering other numbers than intended. The problem is that your program crashes, when the user enters not even a number (for example "hi"). This can be solved with the following code (use import java.util.InputMismatchException;):

while(true) {
        try {
            numItems = scn.nextInt();
            if(numItems &lt; 1 || 10 &lt; numItems) {
                throw new InputMismatchException()
            }
            break;
        }
        catch(InputMismatchException e) {
            System.out.println("Invalid Input!");
            scn.nextLine();
        }
}


Also, you have initialized more than one scanner in your program. That's not necessary. Just initialize one in the beginning and use it for the whole time.



Other


I removed the variable errors, because it is not useful to tell the user how many errors he/she made. But that's just a personal opinion.
It's not necessary to restrict the number of items and their prices, but I have left it in the code so you can see how to restrict it.


All in all your code could look like this:

import java.util.Scanner;
import java.util.InputMismatchException;

public class Taxes {

    public static void main(String[] args) {

        double subtotal = 0;
        Scanner scan = new Scanner(System.in);
        System.out.println("Please enter the number of items bought (1-10): ");
        int numItems;
        while(true) {
            try {
                numItems = scan.nextInt();
                if(numItems &lt; 1 || 10 &lt; numItems) {
                    throw new InputMismatchException();
                }
                break;
            }
            catch(InputMismatchException e) {
                System.out.println("Invalid Input!");
                scan.nextLine();
            }
        }

        for (int i = 1; i &lt;= numItems; i++) {
            System.out.println("Please enter the price of item " + i);
            Double itemCost;
            while(true) {
                try {
                    itemCost = scan.nextDouble();
                    if(itemCost &lt; 1 || 1000 &lt; itemCost) {
                        throw new InputMismatchException();
                    }
                    break;
                }
                catch(InputMismatchException e) {
                    System.out.println("Invalid Input!");
                    scan.nextLine();
                }
            }
            subtotal += itemCost;
        }
        System.out.println("Please enter the tax rate of GST in %: ");
        double gRate;
        while(true) {
            try {
                gRate = scan.nextDouble();
                if(gRate &lt; 0 || 14 &lt; gRate) {
                    throw new InputMismatchException();
                }
                break;
            }
            catch(InputMismatchException e) {
                System.out.println("Invalid Input!");
                scan.nextLine();
            }
        }
        System.out.println("Please enter the tax rate of QST in %: ");
        double qRate;

        while(true) {
            try {
                qRate = scan.nextDouble();
                if(qRate &lt; 0 || 17 &lt; qRate) {
                    throw new InputMismatchException();
                }
                break;
            }
            catch(InputMismatchException e) {
                System.out.println("Invalid Input!");
                scan.nextLine();
            }
        }

        calculate(subtotal, gRate, qRate);
    }


    public static void calculate(double subtotal, double gRate, double qRate) {
        double gst = subtotal * (gRate/100); 
        double qst = (subtotal + gst) * (qRate/100);
        double total = subtotal + gst + qst;
        System.out.println("GST: " + gst);
        System.out.println("QST: " + qst);
        System.out.println("Subtotal: "  + total);
    }
}


I will leave it to you to comment the code properly.