A CLI calculator that can do basic calculations and can solve geometric formulas using a built in template

This is an update for my old post, "CLI Calculator that can solve built-in formulas and basic equations." Here I made some changes to the code, by splitting it up into many classes. In the previous version, my program ran from one big main class. Here, I split it into multiple classes. I think I should mention that I am a beginner, but I think I am getting better.

Main Class

import java.util.Scanner;

public class Main {

public static void main(String[] args) {
boolean logout = false;
Second second = new Second();
while (!logout) { //This loop scans the input for logout
Scanner strCommand = new Scanner(System.in);
second.mainMenu(strCommand); //This switches the class

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

}

}
}


That is the main class. It is not much really, it's just a loop that keeps the calculator running, until the user types "logout".

Second Class

import java.util.Scanner;

public class Second {

public void mainMenu(Scanner scanner) {
Scanner in = new Scanner(System.in);
Scanner input = new Scanner(System.in);
Scanner strIn = new Scanner(System.in);
System.out.println("Ribchinski Calculator 2.0   June 2017");
System.out.println("Choose an option:");
System.out.println("Surface Area | Volume | Calculator");
String formType = scanner.nextLine();

switch (formType.toLowerCase()) {
case "calculator":
Calculator.calcMenu(input);
break;
case "volume":
Volume.volMenu(in);
break;
case "surface area":
Area.arMenu(strIn);
break;
}

}
}


This class I should've called "Mmenu", because it serves as the main menu of the program. It is small, and you probably don't really need explaining about this class.

Area Class

import java.util.Scanner;

public class Area {

public static void arMenu(Scanner strIn){
String equ;
Scanner numIn = new Scanner(System.in);
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 = strIn.nextLine();

switch (equ.toLowerCase()){
case "cube":
System.out.println("Please input the side length of a cube: ");
double anum = numIn.nextDouble();
System.out.println("The surface area of the cube is:");
System.out.println(Math.pow(anum, 2) * 6);
break;
case "rectangular prism":
System.out.println("Side A:");
anum = numIn.nextDouble();
System.out.println("Side B:");
double bnum = numIn.nextDouble();
System.out.println("Side C:");
double 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 * Math.pow(anum, 2));
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;
}
}
}


This class processes the geometric area formulas via built-in formulas. I did it the most basic way, the variables in the formula are just replaced by the variables of the program. It's simple, but I don't know how to make it more compact. It works, though. You don't have to check the formulas, they are all right.

Volume Class

import java.util.Scanner;

public class Volume {

public static void volMenu(Scanner in) {
String choice;
Scanner numIn = new Scanner(System.in);
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");
choice = in.nextLine();

switch (choice.toLowerCase()){
case "cube":
System.out.println("Please input the side length of a cube:");
double 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:");
double bnum = numIn.nextDouble();
System.out.println("Please input the height of the Rectangular Prism:");
double 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((anum * bnum * cnum) / 3);
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((Math.PI * Math.pow(anum, 2) * bnum) / 3);
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((Math.PI * Math.pow(anum, 3) * 4) / 3);
break;
}

}

}


It's the same thing as the previous class, but instead of using area formulas it uses volume formulas. Very simple.

Calculator Class

import java.util.Scanner;

public class Calculator {

public static void calcMenu(Scanner input){
Scanner oper = new Scanner(System.in);
System.out.println("Please input the First number:");
double anum = input.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 = oper.nextLine();

System.out.println("Please input the Second number:");
double bnum = input.nextDouble();

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

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

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

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


This is probably the simplest piece of code in my whole program. Before I made this multipurpose calculator, I made this code. I made this just when I learned how to use Scanner. Then when I started working on the multipurpose calculator, I didn't know how to make a calculator any other way than this, so I just copy and pasted the code from my old program. After I get tips on how to improve this program, I am going to try and make the calculator function like a normal one, meaning that you can input any amount of numbers as you want.

If you want the code without the explanations, and want to try out my program, click here.

1 Answer

This class I should've called "Mmenu", because it serves as the Main Menu of the program. It is small, and you probably don't really need explaining about this class.

I agree that Second is a horribly non-descriptive name, but I would never call a class MMenu to indicate that it is the main menu. Either go ahead and call it MainMenu or just Menu.

        Scanner in = new Scanner(System.in);
Scanner input = new Scanner(System.in);
Scanner strIn = new Scanner(System.in);
System.out.println("Ribchinski Calculator 2.0   June 2017");
System.out.println("Choose an option:");
System.out.println("Surface Area | Volume | Calculator");
String formType = scanner.nextLine();

switch (formType.toLowerCase()) {
case "calculator":
Calculator.calcMenu(input);
break;
case "volume":
Volume.volMenu(in);
break;
case "surface area":
Area.arMenu(strIn);
break;
}


You only need one Scanner per input type per program.

        System.out.println("Ribchinski Calculator 2.0   June 2017");
System.out.println("Choose an option:");
System.out.println("Surface (A)rea | (V)olume | (C)alculator");

try (Scanner input = new Scanner(System.in)) {
SubApplication menu = chooseApplication(input);
menu.process();
}


And here's the chooseApplication method.

    public static SubApplication chooseApplication(Scanner input) {
String formType = input.nextLine();

switch (formType.toLowerCase().charAt(0)) {
case 'c':
return new Calculator(input);
case 'v':
return new Volume(input);
case 's':
case 'a':
return new Area(input);
}
}


This does the output first. Then it puts the input section with just a single Scanner.

This uses the try-with-resources form to manage the Scanner. This ensures that it closes even if an exception is thrown. You could also just use scanner, but I wanted to show how the try-with-resources works.

The Application interface provides a common set of operations. So far we only seem to need process.

I would not call a method menu. The word menu is a noun. It should represent a thing like an object or class. A method is an action. We'd represent it with a verb like process or showMenu.

I changed things so that instead of operating off strings, it will choose based on the first letter. You will be running the program a lot. You might as well do things the easy way for input. And if you really want to type out the word, you can type swear words instead. Just so long as they start with the right letter. Or you can type out the real words.

As written, this will crash without a valid selection. I don't know that that matters much. In the original, it would just silently end in that case. You might do better with a loop that lasts until a valid selection is made. If it's important, you could check that menu != null before using it.

interface SubApplication {

void process();

}


And then you'd say something like

class Calculator extends SubApplication {

private final Scanner input;

Calculator(Scanner input) {
this.input = input;
}

@Override
public void process() {


Feel free to change the name SubApplication. I didn't really like Application, as other things use that. But I don't really have a better name. Perhaps you do.

• .get doesn't work for some reason. – ViceroyFaust Aug 26 '17 at 17:35