Creating a calculator but can't exit

Viewed 372

I need help with my coding. I am practicing again with my java programming and today I am creating a calculator that has the same function as the real calculator but again I run into errors and unable to figure out again.

Okay, the way I wanted my calculator to works is instead of getting line by line input from the user like this:-

In code output

Enter Number: 1
Enter Operator (+,-, /, *, ^ (Power)  or  s (Square): +
Enter Number: 2
Ans: 3

I wanted it to calculate when the user press enter like this:-

The Output that I want

enter number: 1+2*4 
Ans: 12

So they can add as many long numbers as they want before they hit enter calculate. The users are supposed to be able to reset the number to when using the calculator while in the loop of the calculation.

at the beginning of the code, it will ask the user for an input to continue or exit the calculator. Then if continue it will run the calculation. The calculator will be looping until the users press E to exit the calculator and if exit it will exit the code.

This is where I have errors. First, I can't figure out how to break from the loop inside the looping calculator and second at the beginning of the code when the user press E it was supposed to exit the calculator but it didn't. The third error is when the user using the square to calculate I want it to get straight to show the answer instead of asking another number.

and I want to simplify the code in public static void main(String[] args)for the calculation part. Is it possible to put the switch case in method and call it inside the main? or do you have a suggestion on how to simplify the calculation part?

Please help me:(

public class TestingCalculator {

     public static void main(String[] args){

          double answer = 0;
          double numA, numB;
          char operator;

          char activateCalc; 
          boolean calculator = false;

          System.out.println("Welcome to the Calculator.");
          System.out.print(" Continue (Press Y) \n Exit (Press E) \n: ");

          Scanner ans = new Scanner(System.in);
          String a = ans.next();
          activateCalc = a.charAt(0);

          while (activateCalc != 'E' || activateCalc != 'e') {

               Scanner input = new Scanner(System.in);

               System.out.print("Enter number: "); 

               String n =input.next();
               numA = Double.parseDouble(n); 

               while (calculator = true) {

                     //User enter their operator.
                    System.out.print("Enter Operator (+,-, /, *, ^ (Power)  or  s (Square): ");
                    operator = input.next().charAt(0);

                    System.out.print("Enter number: ");  //User enter the continues number
                    numB = input.nextDouble();


                     switch (operator) {

                          case '=':
                               System.out.print(answer);   
                               break;
                          case '+':
                               answer = add(numA,numB);  
                               break;
                         case '-':
                               answer =subtract(numA,numB);
                              break;
                         case '*':
                               answer = multiply(numA,numB);
                               break;
                         case '/':
                               answer = divide(numA,numB);
                               break;
                         case '^':
                              answer = power(numA, numB);
                               break;
                         case 's':
                         case 'S':
                               answer = Math.pow(numA, 2);
                              break;
               }

               //The calculation answer of the user input
               System.out.println("Answer: " + answer);
               numA = answer;

               // to exit calculator.
               System.out.println("Press E to Exit the calculator: ");

                    if (activateCalc = 'E' || activateCalc = 'e') {
                         break;
                    }

               }  
          }

          ans.close();
     }

     //Method for the operators.
    static double add(double numA, double numB) {

          double answer =  numA + numB;
          return answer;
     }

    static double subtract(double numA, double numB) {

          double answer = numA - numB;
          return answer;        
     }

     static double multiply(double numA, double numB) {

          double answer = numA * numB;
          return answer;   
     }

     static double divide(double numA, double numB) {

          double answer = numA / numB;
          return answer;
     }    
     static double power(double numA, double numB) {

          int answer = (int) Math.pow(numA, numB);
          return answer;
     }    
     static double Square(double numA, double numB) {

          int answer = (int) Math.pow(numA, 2);
          return answer;
     }    
}
3 Answers

try below code and one suggestion try to handle the negative scenarios as well.

public static void main(String[] args) {

    double answer = 0;
    double numA, numB;
    char operator;

    char activateCalc;
    boolean calculator = false;

    System.out.println("Welcome to the Calculator.");
    System.out.print(" Continue (Press Y) \n Exit (Press E) \n: ");

    Scanner ans = new Scanner(System.in);
    Scanner input = new Scanner(System.in);
    activateCalc = input.next().charAt(0);
    while (true) {
        if (activateCalc != 'E' && activateCalc != 'e') {
            System.out.print("Enter number: ");

            String n = input.next();
            numA = Double.parseDouble(n);

            // User enter their operator.
            System.out.print("Enter Operator (+,-, /, *, ^ (Power)  or  s (Square): ");
            operator = input.next().charAt(0);

            System.out.print("Enter number: "); // User enter the continues number
            numB = input.nextDouble();

            switch (operator) {

            case '=':
                System.out.print(answer);
                break;
            case '+':
                answer = add(numA, numB);
                break;
            case '-':
                answer = subtract(numA, numB);
                break;
            case '*':
                answer = multiply(numA, numB);
                break;
            case '/':
                answer = divide(numA, numB);
                break;
            case '^':
                answer = power(numA, numB);
                break;
            case 'S':
            case 's':
                answer = Math.pow(numA, 2);
                break;
            default:
                answer = 0;
            }

            // The calculation answer of the user input
            System.out.println("Answer: " + answer);
            numA = answer;

            // to exit calculator.
            System.out.println("Press E to Exit the calculator or Y to continue : ");
            activateCalc = input.next().charAt(0);
            if(activateCalc != 'E' && activateCalc != 'e')continue;
        }
        System.out.println("Thank you for using the calculator. By :) ");
        ans.close();
        break;
    }

}

// Method for the operators.
static double add(double numA, double numB) {

    double answer = numA + numB;
    return answer;
}

static double subtract(double numA, double numB) {

    double answer = numA - numB;
    return answer;
}

static double multiply(double numA, double numB) {

    double answer = numA * numB;
    return answer;
}

static double divide(double numA, double numB) {

    double answer = numA / numB;
    return answer;
}

static double power(double numA, double numB) {

    int answer = (int) Math.pow(numA, numB);
    return answer;
}

static double Square(double numA, double numB) {

    int answer = (int) Math.pow(numA, 2);
    return answer;
}

This question requires debugging details so here we go:

  1. Your code does not seem to compile because of the error:
if (activateCalc = 'E' || activateCalc = 'e') {
    break;
}

where you had to use comparison == operator instead of assignment =.

  1. Similar issue is in your inner loop while (calculator = true) - and there's a warning that this value is never used - but this does not affect much.

  2. You cannot exit the loop because you never check the input for exit, it should be:

System.out.println("Press E to Exit the calculator: ");
activateCalc = input.next().charAt(0);
  1. But even if you updated activateCalc, you'd get into endless loop anyway because of the error in this condition while (activateCalc != 'E' || activateCalc != 'e') -- even if user presses 'e', or 'E' this condition is always true.

Instead of trying to identify the problems with your application, I decided to focus on producing a program that works the way you want (with the input you specified). The code was a little big, but I tried to leave it well commented for you to understand what I did. I know that some things may still be a little confusing, so I will simulate running the program to try to make it clearer how it works.

Code

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;


public class TestingCalculator 
{
    //-------------------------------------------------------------------------
    //      Methods
    //-------------------------------------------------------------------------
    /**
     * Evaluates a mathematical expression.
     * 
     * @param       line Mathematical expression. This line cannot have blank
     * spaces
     * @return      Result of this mathematical expression
     */
    public static String calc(String line)
    {
        while (!hasOnlyNumbers(line)) {
            // Checks if line has parentheses
            if (line.contains("(")) {
                // Get index of the most nested parentheses
                int parentheses_begin = line.lastIndexOf("(");
                int parentheses_end = line.substring(parentheses_begin).indexOf(")");
                String ans = calc(line.substring(parentheses_begin+1, parentheses_end));

                // Replaces content of parentheses with the result obtained
                if (line.length()-1 >= parentheses_end+1)
                    line = line.substring(0,parentheses_begin)+ans+line.substring(parentheses_end+1);
                else
                    line = line.substring(0,parentheses_begin)+ans;
            }
            // Checks if line has potentiation operator
            else if (line.contains("^")) {
                int opIndex = line.indexOf("^");
                String n1 = extractFirstNumber(line, opIndex);
                String n2 = extractSecondNumber(line, opIndex);
                double ans = power(Double.valueOf(n1), Double.valueOf(n2));

                line = calc(parseLine(line, n1, n2, opIndex, ans));
            }
            // Checks if line has square operator
            else if (line.contains("s")) {
                int opIndex = line.indexOf("s");
                String n1 = extractFirstNumber(line, opIndex);
                double ans = square(Double.valueOf(n1));

                line = calc(parseLine(line, n1, opIndex, ans));
            }
            // Checks if line has multiplication operator
            else if (line.contains("*")) {
                int opIndex = line.indexOf("*");
                String n1 = extractFirstNumber(line, opIndex);
                String n2 = extractSecondNumber(line, opIndex);
                double ans = multiply(Double.valueOf(n1), Double.valueOf(n2));

                line = calc(parseLine(line, n1, n2, opIndex, ans));
            }
            // Checks if line has division operator
            else if (line.contains("/")) {
                int opIndex = line.indexOf("/");
                String n1 = extractFirstNumber(line, opIndex);
                String n2 = extractSecondNumber(line, opIndex);
                double ans = divide(Double.valueOf(n1), Double.valueOf(n2));

                line = calc(parseLine(line, n1, n2, opIndex, ans));
            }
            // Checks if line has sum operator
            else if (line.contains("+")) {
                int opIndex = line.indexOf("+");
                String n1 = extractFirstNumber(line, opIndex);
                String n2 = extractSecondNumber(line, opIndex);
                double ans = add(Double.valueOf(n1), Double.valueOf(n2));

                line = calc(parseLine(line, n1, n2, opIndex, ans));
            }
            // Checks if line has subtraction operator
            else if (line.contains("-")) {
                int opIndex = line.indexOf("-");
                String n1 = extractFirstNumber(line, opIndex);
                String n2 = extractSecondNumber(line, opIndex);
                double ans = subtract(Double.valueOf(n1), Double.valueOf(n2));

                line = calc(parseLine(line, n1, n2, opIndex, ans));
            }
        }

        // Returns line only when it has only numbers
        return line;
    }

    /**
     * Checks if a line contains only numbers.
     * 
     * @param       line Line to be analyzed
     * @return      If a line contains only numbers
     */
    private static boolean hasOnlyNumbers(String line)
    {
        return line.matches("^[0-9.]+$");
    }

    /**
     * Given a mathematical expression, replaces a subexpression for a value.
     * 
     * @param       line Mathematical expression
     * @param       n1 Number to the left of the subexpression operator
     * @param       n2 Number to the right of the subexpression operator
     * @param       opIndex Operator index of the subexpression
     * @param       ans Value that will replace the subexpression
     * @return      New mathematical expression with the subexpression replaced
     * by the value
     */
    private static String parseLine(String line, String n1, String n2, int opIndex, double ans)
    {
        int lenFirstNumber = n1.length();
        int lenSecondNumber = n2.length();

        if (line.length()-1 >= opIndex+lenSecondNumber+1)
            return line.substring(0, opIndex-lenFirstNumber)+ans+line.substring(opIndex+lenSecondNumber+1);

        return line.substring(0, opIndex-lenFirstNumber)+ans;
    }

    /**
     * Given a mathematical expression, replaces a subexpression for a value.
     * 
     * @param       line Mathematical expression
     * @param       n1 Number to the left of the subexpression operator
     * @param       opIndex Operator index of the subexpression
     * @param       ans Value that will replace the subexpression
     * @return      New mathematical expression with the subexpression replaced
     * by the value
     */
    private static String parseLine(String line, String n1, int opIndex, double ans)
    {
        int lenFirstNumber = n1.length();

        if (line.length()-1 >= opIndex+2)
            return line.substring(0, opIndex-lenFirstNumber)+ans+line.substring(opIndex+2);

        return line.substring(0, opIndex-lenFirstNumber)+ans;
    }

    /**
     * Extracts the first number from an operation. <br />
     * <h1>Example:<h1> <br />
     *  <b>Line:</b>        1+2*3   <br />
     *  <b>opIndex:</b>     3       <br />
     *  <b>Return:</b>      2       <br />
     * 
     * @param       line Mathematical expression
     * @param       opIndex Index of the operator to which the number to be 
     * extracted belongs to
     * @return      Number to the left of the operator
     */
    private static String extractFirstNumber(String line, int opIndex)
    {
        StringBuilder num = new StringBuilder();
        int i = opIndex-1;

        while (i>=0 && (Character.isDigit(line.charAt(i)) || line.charAt(i) == '.')) {
            num.append(line.charAt(i));
            i--;
        }

        // Reverses the result, since the number is taken from the end to the 
        // beginning
        num = num.reverse();

        return num.toString();
    }

    /**
     * Extracts the second number from a math operation. <br />
     * <h1>Example:<h1> <br />
     *  <b>Line:</b>        1+2*3   <br />
     *  <b>opIndex:</b>     3       <br />
     *  <b>Return:</b>      3       <br />
     * 
     * @param       line Mathematical expression
     * @param       opIndex Index of the operator to which the number to be 
     * extracted belongs to
     * @return      Number to the right of the operator
     */
    private static String extractSecondNumber(String line, int opIndex)
    {
        StringBuilder num = new StringBuilder();
        int i = opIndex+1;

        while (i<line.length() && (Character.isDigit(line.charAt(i)) || line.charAt(i) == '.')) {
            num.append(line.charAt(i));
            i++;
        }

        return num.toString();
    }

    // Method for the operators.
    private static double add(double numA, double numB) 
    {
        double answer = numA + numB;
        return answer;
    }

    private static double subtract(double numA, double numB) 
    {
        double answer = numA - numB;
        return answer;
    }

    private static double multiply(double numA, double numB) 
    {
        double answer = numA * numB;
        return answer;
    }

    private static double divide(double numA, double numB) 
    {
        double answer = numA / numB;
        return answer;
    }

    private static double power(double numA, double numB) 
    {
        int answer = (int) Math.pow(numA, numB);
        return answer;
    }

    private static double square(double num) 
    {
        int answer = (int) Math.pow(num, 2);
        return answer;
    }

    //-------------------------------------------------------------------------
    //      Main
    //-------------------------------------------------------------------------
    public static void main(String[] args) throws IOException 
    {
        char option;
        String inputLine = "";
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));

        System.out.println("Welcome to the Calculator.");
        System.out.print(" Continue (Press Y) \n Exit (Press E) \n: ");

        option = input.readLine().charAt(0);

        while (option != 'E' && option != 'e') {
            // Gets user input
            System.out.print("Enter mathematical expression: ");

            inputLine += input.readLine();

            // Processes input
            inputLine = inputLine.replaceAll(" ", "");
            inputLine = inputLine.replaceAll("S", "s");

            // Evaluates input
            System.out.println("Evaluating...");
            String ans = TestingCalculator.calc(inputLine);

            // Displays answer
            System.out.println("Ans: "+ans);

            // Checks if the user wants to continue running the program
            System.out.print("Press E to Exit the calculator: ");

            inputLine = input.readLine();

            if (inputLine.length() > 0)
                option = inputLine.charAt(0);
        }

        input.close();
    }
}

Output

Enter mathematical expression: (1+2*4)/3
Evaluating...
Ans: 3.0

Output 2

Enter mathematical expression: 1+2*9/3
Evaluating...
Ans: 7.0

Desk checking

Input: (1+2*4)/3


    calc( (1+2*4)/3 )
        not hasOnlyNumbers( (1+2*4)/3) ) ? true
        ( (1+2*4)/3) ) contains '(' ? true
            int parentheses_begin = 0
            int parentheses_end = 6
            String ans = calc( 1+2*4 )
                calc( 1+2*4 )
                    not hasOnlyNumbers( 1+2*4 ) ? true
                    ( 1+2*4 ) contains '(' ? false
                    ( 1+2*4 ) contains '^' ? false
                    ( 1+2*4 ) contains 's' ? false
                    ( 1+2*4 ) contains '*' ? true
                        int opIndex = 3
                        int n1 = 2
                        int n2 = 4
                        String ans = n1 * n2 = 2 * 4 = 8

                        line = calc( 1+8 )
                            calc( 1+8 )
                                not hasOnlyNumbers( 1+8 ) ? true
                                ( 1+8 ) contains '(' ? false
                                ( 1+8 ) contains '^' ? false
                                ( 1+8 ) contains 's' ? false
                                ( 1+8 ) contains '*' ? false
                                ( 1+8 ) contains '/' ? false
                                ( 1+8 ) contains '+' ? true
                                    int opIndex = 1
                                    int n1 = 1
                                    int n2 = 8
                                    String ans = n1 + n2 = 1 + 8 = 9
                                    line = calc( 9 )
                                        calc( 9 )
                                            not hasOnlyNumbers( 9 ) ? false
                                            return 9
                                    line = 9
                                not hasOnlyNumbers( 9 ) ? false
                                return 9
                        line = 9
                    not hasOnlyNumbers( 9 ) ? false
                    return 9
            ans = 9
            (9-1 >= 6+1) ? true
                line = 9/3
        not hasOnlyNumbers( 9/3 ) ? true
        ( 9/3 ) contains '(' ? false
        ( 9/3 ) contains '^' ? false
        ( 9/3 ) contains 's' ? false
        ( 9/3 ) contains '*' ? false
        ( 9/3 ) contains '/' ? true
            int opIndex = 1
            String n1 = 9
            String n2 = 3
            double ans = 9 / 3 = 3

            line = calc( 3 )
                calc( 3 )
                    not hasOnlyNumbers( 3 ) ? false
                    return 3
            line = 3
        not hasOnlyNumbers( 3 ) ? false
        return 3

Some observations

  • No checks are made to see if the user-provided input is valid
  • It is important to maintain the order of operations that are verified in the calc method, in order to maintain precedence between operators (exponentiation / radication must be done first, followed by multiplication / division and finally addition / subtraction operations)
  • I had problems with the Scanner class, so I used BufferedReader to read the input
  • Square operation must be done as follows: <num>s or <num>S

Hope this helps. If you don't understand something, tell me I can explain it to you.

Related