5
\$\begingroup\$

I am just a java beginner — so this program is very basic. It works as intended but I think it's a bit too repetitive and it probably uses more resources than intended. Also, I cannot run this from jar, because I have no idea how to use swing.

      import java.util.Scanner;

 public class Formula {

public static void main(String[] args) {
    boolean logout = false;
    while (!logout) {
        Scanner strCommand = new Scanner(System.in);

        System.out.println("Action ([continue], logout) ?");
        String command = strCommand.nextLine();
        if (command.equalsIgnoreCase("logout")) {
            System.exit(0);
        }

        Scanner numIn = new Scanner(System.in);
        Scanner strIn = new Scanner(System.in);
        Scanner choice = new Scanner(System.in);
        double anum, bnum, cnum, dnum;
        String formType, equ;

        System.out.println("Choose an option:");
        System.out.println("Surface Area | Volume | Calculator");
        formType = strIn.nextLine();

        switch (formType.toLowerCase()) {
        case "calculator":
            System.out.println("Please input the First number:");
            anum = numIn.nextDouble();
            System.out.println("Please input the Second number:");
            bnum = numIn.nextDouble();

            System.out.println("Please input on of the following operations:");
            System.out.println("+");
            System.out.println("-");
            System.out.println("*");
            System.out.println("/");
            equ = strIn.nextLine();

            switch (equ.toLowerCase()) {
            case "+":
                System.out.println("The answer is:");
                System.out.println(anum + bnum);
                break;

            case "-":
                System.out.println("The answer is:");
                System.out.println(anum - bnum);
                break;

            case "*":
                System.out.println("The answer is:");
                System.out.println(anum * bnum);
                break;

            case "/":
                System.out.println("The answer is:");
                System.out.println(anum / bnum);
                break;
            }
            break;

        case "volume":
            System.out.println("Choose one of the following formulas:");
            System.out.println("Cube");
            System.out.println("Rectangular Prism");
            System.out.println("Cylinder");
            System.out.println("Pyramid");
            System.out.println("Cone");
            System.out.println("Sphere");
            equ = choice.nextLine();

            switch (equ.toLowerCase()) {
            case "cube":
                System.out.println("Please input the side length of a cube:");
                anum = numIn.nextDouble();
                System.out.println("The Volume of the Cube is:");
                System.out.println(Math.pow(anum, 3));
                break;

            case "rectangular prism":
                System.out.println("Please input the length of the Rectangular Prism:");
                anum = numIn.nextDouble();
                System.out.println("Please input the width of the Rectangular Prism:");
                bnum = numIn.nextDouble();
                System.out.println("Please input the height of the Rectangular Prism:");
                cnum = numIn.nextDouble();
                System.out.println("The volume of the Rectangular Prism is:");
                System.out.println(anum * bnum * cnum);
                break;

            case "cylinder":
                System.out.println("Please input the Radius of the Cylinder's Base:");
                anum = numIn.nextDouble();
                System.out.println("Please input the Height of the Cylinder:");
                bnum = numIn.nextDouble();
                System.out.println("The Volume of the Cylinder is:");
                System.out.println(Math.PI * Math.pow(anum, 2) * bnum);
                break;

            case "pyramid":
                System.out.println("Please input Side 1 of the Pyramid's Base:");
                anum = numIn.nextDouble();
                System.out.println("Please input Side 2 of the Pyramid's Base:");
                bnum = numIn.nextDouble();
                System.out.println("Please input the Height of the Pyramid:");
                cnum = numIn.nextDouble();
                System.out.println("The Pyramid's Volume is:");
                System.out.println((1 / 3) * (anum * bnum) * cnum);
                break;

            case "cone":
                System.out.println("Please input the Radius of the Base:");
                anum = numIn.nextDouble();
                System.out.println("Please input the Height of the Cone:");
                bnum = numIn.nextDouble();
                System.out.println("The Volume of the Cone is:");
                System.out.println((1 / 3) * Math.PI * Math.pow(anum, 2) * bnum);
                break;

            case "sphere":
                System.out.println("Please input the Radius of the Sphere:");
                anum = numIn.nextDouble();
                System.out.println("The Volume of the Sphere is:");
                System.out.println((4 / 3) * Math.PI * Math.pow(anum, 3));
                break;
            }
            break;

        case "surface area":
            System.out.println("Choose one of the following formulas:");
            System.out.println("Cube");
            System.out.println("Rectangular Prism");
            System.out.println("Sphere");
            System.out.println("Cylinder");
            equ = choice.nextLine();

            switch (equ.toLowerCase()) {
            case "cube":
                System.out.println("Please input the side length of a cube: ");
                anum = numIn.nextDouble();
                System.out.println("The surface area of the cube is:");
                System.out.println(anum * anum * 6);
                break;

            case "rectangular prism":
                System.out.println("Side A:");
                anum = numIn.nextDouble();
                System.out.println("Side B:");
                bnum = numIn.nextDouble();
                System.out.println("Side C:");
                cnum = numIn.nextDouble();
                System.out.println((2 * anum * bnum) + (2 * bnum * cnum) + (2 * anum * cnum));
                break;

            case "sphere":
                System.out.println("Input the radius of the sphere:");
                anum = numIn.nextDouble();
                System.out.println("The surface area of the Sphere is:");
                System.out.println(4 * Math.PI * (anum * anum));
                break;

            case "cylinder":
                System.out.println("Input the Radius:");
                anum = numIn.nextDouble();
                System.out.println("Input the Height:");
                bnum = numIn.nextDouble();
                System.out.println("The surface area of the Cylinder is:");
                System.out.println((2 * Math.PI * (anum * anum)) * (2 * Math.PI * anum * bnum));
                break;
            }
            break;


        }

    }

  }

}

AS you can see, I use a LOT of System.out.printl(); in the code. I am guessing that that is very Efficient. I do not know much — I just know the basics, so I cannot think of any more efficient way to write code. I still cannot wrap my head around sub-Classes, but I think I am getting the hang of it.

\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

I'm just going to cover one point, single-responsibility principle (known in the trade as SRP).

SRP dictates, pretty self-sufficiently, that each method should have one and only one responsibility. That responsibility could include multiple sub-parts, but the method itself should have one job to do.

Your method has several, let's go over them:

  • Loop until the user states to logout
  • Give the user a main-menu option
  • Give the user a sub-option
  • Gather input for calculations
  • Perform calculations
  • Gather result of calculations
  • Print result of calculations

That's a lot of stuff, not to mention, you have three major categories of calculations as well.

So let's break that down. We first need to create a main 'pump' loop.

boolean logout = false;
while (!logout) {
    Scanner strCommand = new Scanner(System.in);

    System.out.println("Action ([continue], logout) ?");
    String command = strCommand.nextLine();
    if (command.equalsIgnoreCase("logout")) {
        System.exit(0);
    }

You don't actually set logout, but you could. Make this the last thing that happens and we can use the logout variable to indicate when to stop.

boolean logout = false;
while (!logout) {
    Scanner scanner = new Scanner(System.in);
    ...

    System.out.println("Action ([continue], logout) ?");
    String command = scanner.nextLine();
    if (command.equalsIgnoreCase("logout")) {
        logout = true;
    }
}

So this is one responsibility: create a main message pump / loop until the user wants to 'logout'. Now what do we do with our sub-responsibilities?

Well, we need to give the user the main menu. For that we'll create a method:

public void mainMenu(Scanner scanner) {

}

And our loop will call the mainMenu:

boolean logout = false;
while (!logout) {
    Scanner scanner = new Scanner(System.in);
    mainMenu(scanner);

    System.out.println("Action ([continue], logout) ?");
    String command = scanner.nextLine();
    if (command.equalsIgnoreCase("logout")) {
        logout = true;
    }
}

Great! Now we have to do the main menu things.

public void mainMenu(Scanner scanner) {
    System.out.println("Choose an option:");
    System.out.println("Surface Area | Volume | Calculator");
    formType = scanner.nextLine();

    switch (formType.toLowerCase()) {
    case "calculator":
        ...
        break;
    case "volume":
        ...
        break;
    case "surface area":
        ...
        break;
    }
}

So each of these case options can call yet another function that prints the sub menu.

private void calculatorMenu(Scanner scanner) {
    System.out.println("Please input the First number:");
    double anum = scanner.nextDouble();
    System.out.println("Please input the Second number:");
    double bnum = scanner.nextDouble();

    System.out.println("Please input on of the following operations:");
    System.out.println("+");
    System.out.println("-");
    System.out.println("*");
    System.out.println("/");
    String equ = scanner.nextLine();

    switch (equ.toLowerCase()) {
    case "+":
        System.out.println("The answer is:");
        System.out.println(anum + bnum);
        break;

    case "-":
        System.out.println("The answer is:");
        System.out.println(anum - bnum);
        break;

    case "*":
        System.out.println("The answer is:");
        System.out.println(anum * bnum);
        break;

    case "/":
        System.out.println("The answer is:");
        System.out.println(anum / bnum);
        break;
    }
    break;
}

Now our case "calculator" just calls calculatorMenu(scanner);.

You should be able to see where this is going, we're not completely in SRP mode yet, but we're close enough for a beginner. Eventually I would expect that you would create a Calculator class, and go from there, but I don't want to throw too many things at you at once. :)

\$\endgroup\$
4
  • \$\begingroup\$ This is a lot of help! Thank you very much. There's one thing that I do not fully understand though. What does "mainMenu(scanner);" do? \$\endgroup\$ Jun 6, 2017 at 15:06
  • \$\begingroup\$ @Ribchinski It calls the mainMenu method and passes the scanner variable as the scanner argument. Do note that the scanner in mainMenu(scanner) and the scanner in mainMenu(Scanner scanner) do not need to be the same name. See: docs.oracle.com/javase/tutorial/java/javaOO/arguments.html \$\endgroup\$ Jun 6, 2017 at 16:17
  • \$\begingroup\$ Because the calculator menu method is private, I cannot call it from the "choice" class. I am kinda new at calling classes from other classes, so I kinda need some help. \$\endgroup\$ Jun 8, 2017 at 12:30
  • \$\begingroup\$ @Ribchinski The easiest fix for that is to make it public, but I would recommend extracting out your print logic and menu logic, essentially the Calculator.menu() method should return what the menu should look like, then it should be printed in the main method. This way the Calculator class doesn't need to worry about the printing. \$\endgroup\$ Jun 8, 2017 at 13:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.