3
\$\begingroup\$
package calc;

import com.sun.tools.corba.se.idl.constExpr.Equal;    //imports .equals(variable)
import java.util.Scanner;    //imports scanners

public class Calc {

    public static void main(String[] args) {
        boolean go = true;    //sets up loop

        while(go)    //creates loop to top
        {
            System.out.println("Hello this is my calculator!");
            System.out.println("To add, type a, to subtract, type s.");
            System.out.println("To multiply, type m, to divide, type d.");

            Scanner scan = new Scanner(System.in);    //sets up scanners
            Scanner scan1 = new Scanner(System.in);


            String action = scan.nextLine();    //tells comp. to take user input

            if("a".equals(action))    //addition
            {
                System.out.println("Now type in the first number you would like to add.");
                int add1 = scan.nextInt();
                System.out.println("Now type the second number.");
                int add2 = scan.nextInt();
                int add3 = add1 + add2;
                System.out.println(add1 + " added to " + add2 + " equals " + add3 + "!");          
            }
            if("s".equals(action))    //subtraction
            {
                System.out.println("Now type in the first number you would like to subtract.");
                int sub1 = scan.nextInt();
                System.out.println("Now type the second number.");
                int sub2 = scan.nextInt();
                int sub3 = sub1 - sub2;
                System.out.println(sub1 + " subtracted bye " + sub2 + " equals " + sub3 + "!"); 
            }
            if("m".equals(action))    //multiplacation
            {
                System.out.println("Now type in the first number you would like to multiply.");
                int mul1 = scan.nextInt();
                System.out.println("Now type the second number.");
                int mul2 = scan.nextInt();
                int mul3 = mul1 * mul2;
                System.out.println(mul1 + " multiplied bye " + mul2 + " equals " + mul3 + "!"); 
            }
            if("d".equals(action))    //division
            {
                System.out.println("Now type in the first number you would like to divide.");
                int div1 = scan.nextInt();
                System.out.println("Now type the second number.");
                int div2 = scan.nextInt();
                int div3 = div1 / div2;
                System.out.println(div1 + " divided bye " + div2 + " equals " + div3 + "!"); 
            }


            System.out.println("Would you like to start over? (yes,no)");           
            String startOver = scan1.nextLine();

            if("no".equals(startOver))
            {
                go = false;
                System.out.println("Bye");
            }
        }
    }                                  
}
  • Would it be possible to make this more compact?
  • Does this code contain dead code?
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Can you please come up with meaningful titles? \$\endgroup\$
    – Bobby
    Commented Dec 7, 2011 at 8:19
  • 1
    \$\begingroup\$ What's a multiplacation? :) \$\endgroup\$ Commented Dec 7, 2011 at 14:02

3 Answers 3

4
\$\begingroup\$

You do "the same" for all four choices - time to abstract!

import java.util.Scanner;    //imports scanners

public class Calc {

    enum Op {

        ADD("a", "add", "added to"),
        SUB("s", "subtract", "subtracted by"),
        MUL("m", "multiply", "multiplied by"),
        DIV("d", "divide", "divided by");
        public String key;
        public String command;
        public String result;

        Op(String key, String command, String result) {
            this.key = key;
            this.command = command;
            this.result = result;
        }

        public int eval(int x, int y) {
            switch (this) {
                case ADD:
                    return x + y;
                case SUB:
                    return x - y;
                case MUL:
                    return x * y;
                case DIV:
                    return x / y;
                default:
                    throw new AssertionError();
            }
        }
    }

    public static void main(String[] args) {
        while (true) //creates loop to top
        {
            System.out.println("Hello this is my calculator!");
            System.out.println("To add, type a, to subtract, type s.");
            System.out.println("To multiply, type m, to divide, type d.");

            Scanner scan = new Scanner(System.in);    //sets up scanners
            Scanner scan1 = new Scanner(System.in);


            String action = scan.nextLine();    //tells comp. to take user input

            Op op = null;
            for (Op operation : Op.values()) {
                if (operation.key.equals(action)) {
                    op = operation;
                    break;
                }
            }

            if (op != null) {
                System.out.println("Now type in the first number you would like to " + op.command + ".");
                int x = scan.nextInt();
                System.out.println("Now type the second number.");
                int y = scan.nextInt();
                int z = op.eval(x, y);
                System.out.println(x + " " + op.result + " " + x + " equals " + z + "!");
            }

            System.out.println("Would you like to start over? (yes,no)");
            String startOver = scan1.nextLine();

            if ("no".equals(startOver)) {
                System.out.println("Bye");
                return;
            }
        }
    }
}

So all operation specific information is captured in the Op enums. If you want to add other operations like min, max, and, or, xor or mod, you don't have to introduce new if-blocks, just new enums.

\$\endgroup\$
2
  • \$\begingroup\$ I'd like to suggest not to use an Enum here, but a "normal" abstract class with eval being an abstract method and the actual operations being extensions (possibly anonymous in a list or a map mapped to the menu keys). That would get rid of the very "un-object-oriented" switch. \$\endgroup\$
    – RoToRa
    Commented Dec 8, 2011 at 10:49
  • 2
    \$\begingroup\$ That's a matter of taste. Note that an enum can have abstract methods, too, that have to be implemented by its constants ("constant specific methods"). This would avoid the switch as well. See the Operation examples in docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html \$\endgroup\$
    – Landei
    Commented Dec 8, 2011 at 19:09
1
\$\begingroup\$

Little things.

You don't need the, go, variable.

while(true) {
  if("no".equals(startOver))
    {
        System.out.println("Bye");
        break;
    }
}

Also, you could use System.out.printf, to make you code a little easier to read.

System.out.printf("%d divided by %d equals %d!\n", div1, div2, div1 / div2);

The newline char is necessary or all your output will appear on one line. Doing the division, addition or multiplication in the output statement will save you the third variable.

I'm not familiar with the, Scanner, class, I don't think you need two of them.

Important note, you code has no error handling, if a user put text were you were expecting a number, the program will exit with an error. You'll want to catch the error on the nextInt calls, tell the user to only input numbers and read from input again.

\$\endgroup\$
3
  • \$\begingroup\$ thank you, in terms of the string instead of integer, could i use the following? \$\endgroup\$ Commented Dec 7, 2011 at 2:19
  • \$\begingroup\$ to control the reaction to typing in something other than a,s,m,or d by using if(!"a".equals(action) || !"s".equals(action) || !"m".equals(action) || !"d".equals(action)) and then asking for a,s,m, or d again? \$\endgroup\$ Commented Dec 7, 2011 at 2:22
  • \$\begingroup\$ I don't want to get to elaborate with a simple program, since I don't know your requirements. Look into how to use the, continue, keyword to jump back to the top of the while loop. You'll have to catch the exception nextInt it going to throw on error, tell the user there was a problem, then use continue to jump back to the top of the loop. \$\endgroup\$
    – KaizenSoze
    Commented Dec 7, 2011 at 2:41
1
\$\begingroup\$

This line:

import com.sun.tools.corba.se.idl.constExpr.Equal;    //imports .equals(variable)

Is actually not needed/used, and probably not doing what you think it's doing. CORBA is not what one would ordinarily use in a calculator...

The comparison here:

 if("no".equals(startOver))
        {
            go = false;
            System.out.println("Bye");
        }

Actually uses the equals method of the String class. By the way, Kaizen is correct and you don't need two Scanner objects.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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