HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Simple Area of Shape Calculator

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
simpleshapeareacalculator

Problem

So I made this calculator the other day as a small project. I just wanted to know if I remembered the fundamentals. It works fine from the looks of it, but I know there are always ways to improve.

```
package Main;
import java.util.*;
public class calc {
@SuppressWarnings("resource")
private static void circle() {
// TODO Auto-generated method stub
double a_c = 0; //a_c = area of circle

System.out.println("Please enter the radius of the circle.");

Scanner read_r = new Scanner(System.in); // This is the scanner that scan user input.

double r = read_r.nextDouble(); // This is the radius the user enters.

a_c = Math.PI r r ; //a_c stands for area of circle followed by equation.

System.out.print("The area of the circle equals: ");

System.out.println(a_c);// the system is printing the result; the value of a_c

main(null);
}
@SuppressWarnings("resource")
private static void square() {
// TODO Auto-generated method stub

double a_s = 0; // a_s = area of square initial value

System.out.println("Please enter the value of the length of one side of the square.");

Scanner read_s = new Scanner(System.in); // This is the scanner that scan user input.

double s = read_s.nextDouble(); // This is the side length the user enters.

a_s = s*s; //equation for square area = s^2

System.out.print("The area of the square equals: ");

System.out.println(a_s);

main(null);
}
@SuppressWarnings("resource")
private static void triangle() {
// TODO Auto-generated method stub
double a_t = 0; //a_t = area of triangle initial value

System.out.println("Please enter the height of your triangle.");

Scanner read_h = new Scanner(System.in); // This is the scanner that will read height.

int h = read_h.nextInt(); // This is the height the user enters.

System.out.println("Please enter the value for the base of your triangle");

Scanner read_b = new Scanner(System.in); // This is the

Solution

First of all, well done on building a working area calculator. Lets see how we can improve it!

To start off, you have quite a few indentation problems. The definition of the class should not be indented at all, and the methods inside the class should be indented once. For each nesting level, you indent another time.

Also, your class is named calc, but Java classes are supposed to be PascalCase, meaning it should be Calc, with an uppercase c.

Functions

You are using too much vertical space. Not every line needs to have an empty line all around it. Try to group blocks of related lines of code together.

Most, if not all of your functions, do more than one thing. In programming we strive for functions that perform a single task and do so very well. For example, your main function is also in charge of how the user interface is presented to the user. This should be offloaded to another function like so:

private static void showUserOptions() {
    System.out.println("What would you like to do? Type the number of your desired function.");

    System.out.println("1. Area of a Circle");
    System.out.println("2. Area of a Square");
    System.out.println("3. Area of a Triangle");
    System.out.println("4. Area of a Rectangle");
    System.out.println("5. Quit");
}


Now we can simply call this function from the main method. As you can see, I have also grouped the System.out.println() statements that specify the options very close to each other. This helps with readability a lot.

Your functions also contain a lot of code duplication, such as printing the area of the selected shape and creating a new Scanner instance in every function, which is totally unnecessary and can be replaced with a single static instance like so:

private static Scanner inputScanner = new Scanner(System.in);


Furthermore, your variable names are not very clear. a_r is a useless variable name. How about rectangleArea?

User Input

For the user input of your program, we can user Java enums:

private enum UserInput { CIRCLE, SQUARE, TRIANGLE, RECTANGLE, QUIT, INVALID }


Here I have created 4 enum values for the different shapes, a QUIT enum value for the quit command and an INVALID value for any user input that is invalid.

Now we do have to change the showUserOptions() function a bit to make it correspond with the new enum values. This is done as follows:

private static void showUserOptions() {
    System.out.println("What would you like to do? Type the number of your desired function.");

    System.out.println(UserInput.CIRCLE.ordinal() + ". Area of a Circle");
    System.out.println(UserInput.SQUARE.ordinal() + ". Area of a Square");
    System.out.println(UserInput.TRIANGLE.ordinal() + ". Area of a Triangle");
    System.out.println(UserInput.RECTANGLE.ordinal() + ". Area of a Rectangle");
    System.out.println(UserInput.QUIT.ordinal() + ". Quit");
}


Calling ordinal() on an enum will give you the index it has in the list of enum values. Meaning that UserInput.SQUARE.ordinal() will result in 0 and UserInput.QUIT.ordinal() will result in 4.

To retrieve an actual enum object from the integer input provided by the user, the following code can be used:

int input = inputScanner.nextInt();
UserInput userInput = UserInput.values()[input];


UserInput.values() creates an array of the enum values, which looks like this: [CIRCLE, SQUARE, TRIANGLE, RECTANGLE, QUIT, INVALID]. Indexing it with the integer input from the user gives us the actual enum value. The UserInput.values() call actually creates a new array every time it is called, so we will be caching it as a static variable right underneath the declaration of the enum itself:

private enum UserInput { CIRCLE, SQUARE, TRIANGLE, RECTANGLE, QUIT, INVALID }
private static UserInput[] userInputs = UserInput.values();


Since the user can enter any integer value, even ones that are outside the range of the userInputs() array, we create a special function to deal with this and ensure that we always get a UserInput enum:

private static UserInput getUserInputFromInt(int userInput) {
    if (userInput >= 0 && userInput < userInputs.length) {
        return userInputs[userInput];
    }

    return UserInput.INVALID;
}


Since your code contained a lot of duplication of retrieving user input, I have created this function:

private static double askUserForValue(String valueName, UserInput userInput) {
    System.out.println(String.format("Please enter the %s of your %s.", valueName, userInput.toString().toLowerCase()));

    return inputScanner.nextDouble();
}


Which we can call like this:

double radius = askUserForValue("radius", userInput);


To ask the user to provide us the radius of a circle.

Main method

The main method of your program should be concise and clear. Also it should definitely not be called manually from other functions. These other functions have no business calling the mai

Code Snippets

private static void showUserOptions() {
    System.out.println("What would you like to do? Type the number of your desired function.");

    System.out.println("1. Area of a Circle");
    System.out.println("2. Area of a Square");
    System.out.println("3. Area of a Triangle");
    System.out.println("4. Area of a Rectangle");
    System.out.println("5. Quit");
}
private static Scanner inputScanner = new Scanner(System.in);
private enum UserInput { CIRCLE, SQUARE, TRIANGLE, RECTANGLE, QUIT, INVALID }
private static void showUserOptions() {
    System.out.println("What would you like to do? Type the number of your desired function.");

    System.out.println(UserInput.CIRCLE.ordinal() + ". Area of a Circle");
    System.out.println(UserInput.SQUARE.ordinal() + ". Area of a Square");
    System.out.println(UserInput.TRIANGLE.ordinal() + ". Area of a Triangle");
    System.out.println(UserInput.RECTANGLE.ordinal() + ". Area of a Rectangle");
    System.out.println(UserInput.QUIT.ordinal() + ". Quit");
}
int input = inputScanner.nextInt();
UserInput userInput = UserInput.values()[input];

Context

StackExchange Code Review Q#131398, answer score: 7

Revisions (0)

No revisions yet.