Search code examples
javaoopmathjava.util.scannercalculator

(Noob Coder) Basic Calculator Issue + Code Advice


I am a learning Java, and as a personal project aside from my high school assignments, I decided to make some math solving programs for practice.

For a warm up, I decided to write a basic calculator program...and it works...kind of. So...please help me!

Goal:

-> To have a calculator that, with Scanner input, can calculate any sequence of numbers with operators [+, -, /, ^(Math.pow), *]. (ex: 1+2+4+2, etc.)

What works:

-> It can calculate the summation, product, power, difference, and divide two numbers (int or double, but answer is double).

What doesn't work:

-> It cannot have input with any whitespace, or it will get an 'out of bounds' error on the first array (The summation one) and so on

-> It cannot calculate any compound problems (ex: 1+2+3, 3*4^6, etc.).

I plan on adding many other things to this (trig functions, extra powers, etc.), but for now, this needs work. Can someone tell me how to fix these problems?

And most of all:

What are my biggest programming mistakes (other than it not working) that I should watch out for(based on the code you see)? I usually program by sequence and logic, but I feel that I (and my code) could be so much more efficient.

The Code:

import java.util.*;
import java.io.*;
import java.lang.System;
import java.util.stream.*;

public class basicCalculator {
    public static void main(String args[])throws IOException{

    System.out.println("What would you like to calculate?");

    Scanner inputNum = new Scanner(System.in);
    String inputI = inputNum.nextLine();
    Scanner inputScan = new Scanner(inputI);
    Scanner inputScan2 = inputScan.useDelimiter("\\+|\\-|\\/|\\*|\\^|\\s");
    Scanner inputScan3 = new Scanner(inputI);

    double textContent[] =  new double[1000];
    int loopCount = -1;
    int loopCount2 = 1;
    int loopCount3 = 0;
    double[] partOfResult = new double[1000];   

    while(inputScan.hasNextDouble()){
        loopCount++;
        textContent[loopCount] = inputScan.nextDouble();
    }

    while(inputScan3.hasNext()){
        if(inputI.contains("+")){
            partOfResult[loopCount3] = (textContent[loopCount2 - 1] + textContent[loopCount2]);
            loopCount3++;
            loopCount2++;
        }else if(inputI.contains("-")){ 
            partOfResult[loopCount3] = (textContent[loopCount2 - 1] - textContent[loopCount2]);
            loopCount3++;
            loopCount2++;
        }
        else if(inputI.contains("/")){
            partOfResult[loopCount3] = (textContent[loopCount2 - 1] / textContent[loopCount2]);
            loopCount3++;
            loopCount2++;
        }
        else if(inputI.contains("*")){
            partOfResult[loopCount3] = (textContent[loopCount2 - 1] * textContent[loopCount2]);
            loopCount3++;
            loopCount2++;
        }
        else if(inputI.contains("^")){
            partOfResult[loopCount3] = (Math.pow(textContent[loopCount - 1], textContent[loopCount]));
            loopCount3++;
            loopCount2++;
        }
        if(inputScan.hasNext() == false){
            double[] answer = new double[1000];
            for(int i = 0; i <= loopCount3;){
                answer[i] = partOfResult[i] + partOfResult[i+1];
                i++;
            }

            double sum = DoubleStream.of(answer).sum();
            System.out.println("The answer is " + sum);
            break;
        }   
    }       

    inputScan3.close();
    inputScan2.close();
    inputScan.close();
    inputNum.close();
}
}

Thanks!


Solution

  • import java.lang.System;

    This is unnecessary. java.lang is imported without you saying so, so you can already just write System in your code without this line. You can safely remove it.

    Scanner inputScan2 = inputScan.useDelimiter("\\+|\\-|\\/|\\*|\\^|\\s");

    Just because useDelimiter returns a Scanner doesn't mean you need to put it into a variable. You never use inputScan2 again except to close it (and in any case, inputScan2 is equal to inputScan after this line, making it redundant.) So I would shorten the line to this:

    inputScan.useDelimiter("\\+|\\-|\\/|\\*|\\^|\\s");

    and also remove the corresponding line that closes this unused scanner.

    It's kind of weird to have loopCount2 and loopCount3 as separate variables when they're always just one away from each other. It seems like you could get rid of one of them.

    I notice you don't have any methods except the main method. That's not so bad for a relatively small program, but it's best to get into the habit of splitting your code up into methods.

    I notice you don't have any code comments. Comments often help you (and others) understand your code. Especially when the variables are named things like inputScan3 - that name gives a very general idea of the variable, but it doesn't really say why it's different from inputScan, for example. Comments would help with that.

    A line like if(inputI.contains("+")){ is never going to be much good for compound statements - you're checking whether the entire String contains a +, which is not all that relevant if you're processing 4+2*3 because that doesn't tell you whether you're currently doing the addition or the multiplication. You're pretty much going to have to redo the way you check which operation you are doing if you want to handle compound statements.

    I notice you set your answer array to a size of 1000. This is perhaps understandable with your other arrays because you don't know their size when you create them, but for this one, you already know the size - it's loopCount3 + 1. So you can write double[] answer = new double[loopCount3+1]; and save some memory.