Monthly Archives: March 2011

Calculator – Java class

This calculator class is part of a coursework I had to do this year. Thought it might help other people in the same scenario :). Please leave comments if you like it or if you spot a few obvious mistakes I made.
[java]
import java.util.ArrayList;

/**
* @author Joshua Wohle
* This is a simple calculator class. It is based upon taking a string of a complete sum and then calculating
* All it needs to do from there.
*/
public class Calculator {

/**
* String default of memory
*/
public static final String memoryDefault = "0";
/**
* ArrayList containing all the whole history of sums calculated
*/
public static ArrayList<String> history = new ArrayList<String>();
/**
* Array containing all of the numbers (we are talking about floats, so a "." is included)
*/
public static String[] numbers = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "."};

/**
* Array containing all of the basic operators
*/
public static String[] basicOperators = {"+", "-", "/", "*"};
/**
* String containing the current error of the calculator (Initiated by an empty string)
*/
public static String error = "";
/**
* String containing the current memory of the Calculator
*/
public static String memory = memoryDefault;

public static String getError() {
return error;
}

public static void setError(String error) {
Calculator.error = error;
}

public static String getMemory() {
return memory;
}

public static void setMemory(String memory) {
Calculator.memory = memory;
}

public static void clearMemory() {
Calculator.memory = memoryDefault;
}

public Calculator() {
}

/**
* This method calculates a basic sum (which means it only involves any of the 4 basic operations : +,-,/,x)
* @param sum String containing the entire term (sum)
*/
public static String calculateBasicSum(String sum) {
ArrayList<String> terms = getTerms(sum);

if(terms.get(0).equals("")) {
setError("You have to start with a number.");
history.add("Error");
return sum;
}
else if(!verifyTerms(terms)) {
setError("Wrong number format.");
history.add("Error");
return sum;
}

// Go through all of the terms in the list
for(int i = 0; i < terms.size()-1; i++) {

// Check if the term is an operator
if(isOperator(terms.get(i))) {
float firstTerm = Float.parseFloat(terms.get(i-1));
float secondTerm = 0;
boolean doubleOperator = false;
int termToReplace = i+1;

// If the next term is also an operator, do the "special" operation
if(isOperator(terms.get(i+1))) {
doubleOperator = true;
secondTerm = firstTerm; }
else
secondTerm = Float.parseFloat(terms.get(i+1));

if(doubleOperator) {
termToReplace = i;
}

// We already know this is an operator, which means it only has one single char, so we can simply check
// it through this switch loop
switch(terms.get(i).charAt(0)) {
case ‘+’:
terms.set(termToReplace, Float.toString(add(firstTerm, secondTerm)));
break;
case ‘-‘:
terms.set(termToReplace, Float.toString(subtract(firstTerm, secondTerm)));
break;
case ‘*’:
terms.set(termToReplace, Float.toString(multiply(firstTerm, secondTerm)));
break;
case ‘/’:
terms.set(termToReplace, Float.toString(divide(firstTerm, secondTerm)));
break;
default:
setError("Could not identify the operator");
break;
}
}
}

history.add(sum /*+ "=" + terms.get(terms.size()-1)*/);
setError(""); // Reset the error, everything went fine 🙂
return terms.get(terms.size()-1);
}

/**
* This method adds b to a
* @param a float b will be added onto
* @param b float that will be added to a
* @return sum of a and b
*/
public static float add(float a, float b) {
return a+b;
}

/**
* This methods subtracts b from a
* @param a float b will be subtracted from
* @param b float to be subtracted from a
* @return subtraction of a and b
*/
public static float subtract(float a, float b) {
return a-b;
}

/**
* This method simply multiplies a and b
* @param a float to be multiplied with b
* @param b float to be multiplied with a
* @return multiplication of a and b
*/
public static float multiply(float a, float b) {
return a*b;
}

/**
* This method simply divides a by b
* @param a float to be divided by b
* @param b float to divide a
* @return (float) division of a and b
*/
public static float divide(float a, float b) {
return a/b;
}

/**
* This method simply checks if a String (or more a character disguised as a string) is present in an array
* @param s Character disguised as string to be checked to an array
* @param array array to check if it contains s
* @return true or false
*/
public static boolean containsString(String s, String[] array) {

for(int i = 0; i < array.length; i++) {
if(s.equals(array[i]))
return true;
}

return false;
}

/**
* @param s
* @return boolean TRUE if the string s is a number
*/
public static boolean isNumber(String s) {
return containsString(s, numbers);
}

/**
* This method simply checks if a string is a valid number.
* Being a valid number means containing only numbers and 1 single "." (at the most)
* @param s – the number
* @return boolean true if s is a number, false if not
*/
public static boolean isValidNumber(String s) {
boolean isValid = true;
// Nunmber of "." the string contains
int numberOfDots = 0;

// Go through the whole string, character by character
for(int j = 0; j < s.length(); j++) {
if(s.charAt(j) == ‘.’)
numberOfDots++;
}
if(numberOfDots >= 2)
isValid = false;

if(isValid)
return true;
else {
return false;
}
}

/**
* Checks if the string s is an operator
* @param s – the string we’re checking against
* @return boolean true if the string is an operator, false if not
*/
public static boolean isOperator(String s) {
return containsString(s, basicOperators);
}

/**
* Checks if the terms in a list are all valid (contain a single dot)
* @param terms
* @return true if the terms are all valid, false if not
*/
public static boolean verifyTerms(ArrayList<String> terms) {
boolean isValid = true;

for(int i = 0; i < terms.size(); i++) {
String s = terms.get(i);
int numberOfDots = 0;
for(int j = 0; j < s.length(); j++) {
if(s.charAt(j) == ‘.’)
numberOfDots++;
}
if(numberOfDots >= 2)
isValid = false;
}

if(isValid)
return true;
else {
return false;
}
}

/**
* Returns the list of terms that are contained within the string
* @param sum – the sum of which you want the terms
* @return ArrayList<String> the list of terms (operators and numbers)
*/
public static ArrayList<String> getTerms(String sum) {
ArrayList<String> terms = new ArrayList<String>();
int startIndex = 0;
int endIndex = 0;
String lastString = "number";

// Loops through the string in orderto get each individual term
for(int i = 0; i < sum.length(); i++) {
if(lastString.equals("number")) {
if(isNumber(Character.toString(sum.charAt(i)))) {
endIndex++;
lastString = "number";
}
else if(isOperator(Character.toString(sum.charAt(i)))) {
terms.add(sum.substring(startIndex, endIndex));
startIndex = endIndex;
endIndex++;
lastString = "operator";
}
}
else if(lastString.equals("operator")) {
if(isOperator(Character.toString(sum.charAt(i)))) {
terms.add(sum.substring(startIndex, endIndex));
startIndex = endIndex;
endIndex++;
lastString = "operator";
}
else if(isNumber(Character.toString(sum.charAt(i)))) {
terms.add(sum.substring(startIndex, endIndex));
startIndex = endIndex;
endIndex++;
lastString = "number";
}
}
if(i == sum.length()-1) {
terms.add(sum.substring(startIndex, endIndex));
}
}

return terms;
}
}
[/java]