diff --git a/Calc-java b/Calc-java new file mode 160000 index 0000000..0ef3432 --- /dev/null +++ b/Calc-java @@ -0,0 +1 @@ +Subproject commit 0ef3432b02c28920fe3eed9f1c83d0ef1c136fe8 diff --git a/src/main/java/com/zipcodewilmington/scientificcalculator/Console.java b/src/main/java/com/zipcodewilmington/scientificcalculator/Console.java index 83f0e97..a5b1a48 100644 --- a/src/main/java/com/zipcodewilmington/scientificcalculator/Console.java +++ b/src/main/java/com/zipcodewilmington/scientificcalculator/Console.java @@ -17,16 +17,25 @@ public static void println(String output, Object... args) { public static String getStringInput(String prompt) { Scanner scanner = new Scanner(System.in); - println(prompt); + print(prompt); String userInput = scanner.nextLine(); + //scanner.close(); return userInput; } public static Integer getIntegerInput(String prompt) { - return null; + Scanner scanner = new Scanner(System.in); + print(prompt); + Integer userinput = scanner.nextInt(); + //scanner.close(); + return userinput; } public static Double getDoubleInput(String prompt) { - return null; + Scanner scanner = new Scanner(System.in); + print(prompt); + Double userinput = scanner.nextDouble(); + //scanner.close(); + return userinput; } } diff --git a/src/main/java/com/zipcodewilmington/scientificcalculator/CoreFeatures.java b/src/main/java/com/zipcodewilmington/scientificcalculator/CoreFeatures.java new file mode 100644 index 0000000..2c73fe7 --- /dev/null +++ b/src/main/java/com/zipcodewilmington/scientificcalculator/CoreFeatures.java @@ -0,0 +1,155 @@ +package com.zipcodewilmington.scientificcalculator; + +public class CoreFeatures { + + //a state represening the value currently displayed on the calc + private double displayValue; + + //Update the display to ERR if an error occurs (ex: divide by 0) + private boolean errorState; + + //initiate calculator with 0 as default + public CoreFeatures () { + this.displayValue = 0.0; + //not an ERR + this.errorState=false; + + } + + //Get the current # on the display + public double getDisplayValue() { + //pull the display value + return this.displayValue; + } + + //Check for errors + public boolean inErrorState() { + //pull the error state (is it true or false) + return this.errorState; + } + + //Set display to the number entered + public void setDisplay (double value) { + //(if ERR, skip the equation) + if (checkError()) return; + //reset the display value to the number entered + this.displayValue=value; + + } + + //Clear the display + public void clear () { + + //set display to 0 and remove error + this.displayValue=0.0; + this.errorState=false; + + + // Clear terminal by printing lines to simulate clearing + for (int i = 0; i < 50; ++i) { + System.out.println(); + } + System.out.println("Cleared"); + } + + + //Add (if ERR, skip the equation) + public void add(double number) { + if (checkError()) return; + this.displayValue+=number; + } + + + //Subtract (if ERR, skip the equation) + public void subtract (double number) { + if (checkError()) return; + this.displayValue -= number; + } + + //Multiply (if ERR, skip the equation) + public void multiply (double number) { + if (checkError()) return; + this.displayValue *= number; + } + + //Divide (if ERR, skip the equation) + public void divide(double number) { + if (checkError()) return; + if(number ==0) { + setError(); + return; + } + this.displayValue/=number; + } + + //Caclulate the square (if ERR, skip the equation) + public void square () { + if (checkError()) return; + this.displayValue=this.displayValue*this.displayValue; + } + + //Calculate the square root (if ERR, skip the equation) + public void squareRoot() { + if (checkError()) return; + if (this.displayValue<0) { + setError(); + return; + } + this.displayValue=Math.sqrt((this.displayValue)); + } + + //Calculate the variable exponentiation (if ERR, skip the equation) + public void exponentiation(double exponent) { + if (checkError()) return; + this.displayValue=Math.pow(this.displayValue, exponent); + } + + //Calculate the inverse of the number (if ERR, skip the equation) + public void inverse() { + if (checkError()) return; + if (this.displayValue==0) { + setError(); + return; + } + this.displayValue=1/this.displayValue; + } + + //Caclulate the percentage of another number NEW FEATURE #1 + public void percentage(double percent) { + if (checkError()) return; + this.displayValue = (percent/this.displayValue)*100; + + } + + //Takes a decimal and returns the percentage NEW FEATURE #2 + public void decimalToPercentage () { + if (checkError()) return; + this.displayValue*=100; + + } + + //Invert the sign of the number (switch between postive and negative) + //(if ERR, skip the equation) + public void inverseSign() { + if (checkError()) return; + this.displayValue=-this.displayValue; + + } + + + //Set an error state so we can use it to compare + private void setError() { + this.errorState=true; + } + + //check for an error before operation + private boolean checkError() { + if (this.errorState) { + System.out.println("ERR"); + return true; + } + return false; + } + + +} diff --git a/src/main/java/com/zipcodewilmington/scientificcalculator/MainApplication.java b/src/main/java/com/zipcodewilmington/scientificcalculator/MainApplication.java index 5f42132..e0a3795 100644 --- a/src/main/java/com/zipcodewilmington/scientificcalculator/MainApplication.java +++ b/src/main/java/com/zipcodewilmington/scientificcalculator/MainApplication.java @@ -5,13 +5,270 @@ */ public class MainApplication { public static void main(String[] args) { - Console.println("Welcome to my calculator!"); - String s = Console.getStringInput("Enter a string"); - Integer i = Console.getIntegerInput("Enter an integer"); - Double d = Console.getDoubleInput("Enter a double."); - - Console.println("The user input %s as a string", s); - Console.println("The user input %s as a integer", i); - Console.println("The user input %s as a d", d); + System.out.println("\nWelcome to my calculator!\n"); + CoreFeatures cfcalc = new CoreFeatures(); + ScientificCalc sCalc = new ScientificCalc(); + Integer option = -1; + + while (option != 21) { + showOption(); + option = Console.getIntegerInput("choose one of the options above: "); + runOption(option, cfcalc, sCalc); + System.out.println("\n"); + + } + + } + + public static void showOption() { + System.out.println("0. clear display"); + System.out.println("1. add"); + System.out.println("2. subtract"); + System.out.println("3. multiply"); + System.out.println("4. division"); + System.out.println("5. square"); + System.out.println("6. square root"); + System.out.println("7. inverse"); + System.out.println("8. switch sign"); + System.out.println("9. sine"); + System.out.println("10. cosine"); + System.out.println("11. tangent"); + System.out.println("12. inverse sine"); + System.out.println("13. inverse cosine"); + System.out.println("14. inverse tangent"); + System.out.println("15. factorial"); + System.out.println("16. switch display mode"); + System.out.println("17. switch units mode"); + System.out.println("18. memory functions"); + System.out.println("19. calculate percent of number"); + System.out.println("20. decimal to percent"); + System.out.println("21. exit"); + } + + public static String outputConverter(ScientificCalc sCalc, Double x) { + String temp = ""; + int aperiod; + int bperiod; + String parts[]; + + switch (sCalc.getDisplayMode()) { + case "decimal": + temp = String.valueOf(x); + break; + case "hexadecimal": + temp = Double.toHexString(x); + break; + case "binary": + parts = String.valueOf(x).split("\\."); + bperiod = Integer.valueOf(parts[0]); + aperiod = Integer.valueOf(parts[1]); + temp = Integer.toBinaryString(bperiod) + "." + Integer.toBinaryString(aperiod); + break; + case "octal": + parts = String.valueOf(x).split("\\."); + bperiod = Integer.valueOf(parts[0]); + aperiod = Integer.valueOf(parts[1]); + temp = Integer.toOctalString(bperiod) + "." + Integer.toOctalString(aperiod); + break; + default: + + break; + } + + return temp; + } + + public static void runOption(Integer option, CoreFeatures cfcalc, ScientificCalc sCalc) { + + Double userinput; + + boolean isdiplayval = cfcalc.getDisplayValue() != 0.0; + + switch (option) { + case 0: + cfcalc.clear(); + cfcalc.setDisplay(0.0); + break; + case 1: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number: "); + cfcalc.setDisplay(userinput); + } + userinput = Console.getDoubleInput("Enter a number to add to " + cfcalc.getDisplayValue() + " : "); + cfcalc.add(userinput); + System.out.println("=" + outputConverter(sCalc, cfcalc.getDisplayValue())); + break; + case 2: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number: "); + cfcalc.setDisplay(userinput); + } + userinput = Console.getDoubleInput("Enter a number to subtract to " + cfcalc.getDisplayValue() + " : "); + cfcalc.subtract(userinput); + System.out.println("=" + outputConverter(sCalc, cfcalc.getDisplayValue())); + break; + case 3: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number: "); + cfcalc.setDisplay(userinput); + } + userinput = Console.getDoubleInput("Enter a number to multiply to " + cfcalc.getDisplayValue() + " : "); + cfcalc.multiply(userinput); + System.out.println("=" + outputConverter(sCalc, cfcalc.getDisplayValue())); + break; + case 4: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number: "); + cfcalc.setDisplay(userinput); + } + userinput = Console.getDoubleInput("Enter a number to divide to " + cfcalc.getDisplayValue() + " : "); + cfcalc.divide(userinput); + System.out.println("=" + outputConverter(sCalc, cfcalc.getDisplayValue())); + break; + case 5: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number to square: "); + cfcalc.setDisplay(userinput); + } + cfcalc.square(); + System.out.println("=" + outputConverter(sCalc, cfcalc.getDisplayValue())); + break; + case 6: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number to sqaure root: "); + cfcalc.setDisplay(userinput); + } + cfcalc.squareRoot(); + System.out.println("=" + outputConverter(sCalc, cfcalc.getDisplayValue())); + break; + case 7: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number enter a numebr to inverse: "); + cfcalc.setDisplay(userinput); + } + cfcalc.inverse(); + System.out.println("=" + outputConverter(sCalc, cfcalc.getDisplayValue())); + break; + case 8: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number enter a number to switch sign: "); + cfcalc.setDisplay(userinput); + } + cfcalc.inverseSign(); + System.out.println("=" + outputConverter(sCalc, cfcalc.getDisplayValue())); + break; + case 9: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number to get sine of: "); + cfcalc.setDisplay(userinput); + } + System.out.println("sine(" + cfcalc.getDisplayValue() + ")= " + + outputConverter(sCalc, sCalc.sine(cfcalc.getDisplayValue()))); + break; + case 10: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number to get cosine of: "); + cfcalc.setDisplay(userinput); + } + System.out.println("cosine(" + cfcalc.getDisplayValue() + ")= " + + outputConverter(sCalc, sCalc.cosine(cfcalc.getDisplayValue()))); + break; + case 11: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number to get tangent of: "); + cfcalc.setDisplay(userinput); + } + System.out.println("tangent(" + cfcalc.getDisplayValue() + ")= " + + outputConverter(sCalc, sCalc.tangent(cfcalc.getDisplayValue()))); + break; + case 12: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number to get inverse sine of: "); + cfcalc.setDisplay(userinput); + } + System.out.println("inverse sine(" + cfcalc.getDisplayValue() + ")= " + + outputConverter(sCalc, sCalc.inverseSine(cfcalc.getDisplayValue()))); + break; + case 13: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number to get inverse cosine of: "); + cfcalc.setDisplay(userinput); + } + System.out.println("inverse cosine(" + cfcalc.getDisplayValue() + ")= " + + outputConverter(sCalc, sCalc.inverseCosine(cfcalc.getDisplayValue()))); + break; + case 14: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number: enter a number to get inverse tangent of "); + cfcalc.setDisplay(userinput); + } + System.out.println("inverse tangent(" + cfcalc.getDisplayValue() + ")= " + + outputConverter(sCalc, sCalc.inverseTangent(cfcalc.getDisplayValue()))); + break; + case 15: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number to do factorial on: "); + cfcalc.setDisplay(userinput); + } + System.out.println("factorial(" + cfcalc.getDisplayValue() + ")= " + + outputConverter(sCalc, sCalc.factorial(cfcalc.getDisplayValue()))); + break; + case 16: + String temp = ""; + temp = Console.getStringInput( + "type an option or click enter for auto next (decimal, hexadecimal, binary, octal): "); + if (temp.isEmpty()) + sCalc.switchDisplayMode(); + else + sCalc.switchDisplayMode(temp); + + break; + case 17: + String temp2 = ""; + temp2 = Console.getStringInput("type an option or click enter for auto next (radians, degree): "); + if (temp2.isEmpty()) + sCalc.switchUnitsMode(); + else + sCalc.switchUnitsMode(temp2); + break; + case 18: + int x = Console.getIntegerInput( + "Memmory options:\n1.Add a number to memmory\n2.Reset memmory\n3.Recall from memmory\nChoose an option: "); + switch (x) { + case 1: + userinput = Console.getDoubleInput("Enter an number to add to memory: "); + sCalc.memmoryFunctions(userinput, "m+"); + break; + case 2: + sCalc.memmoryFunctions(x, "mc"); + break; + case 3: + sCalc.memmoryFunctions(x, "mrc"); + cfcalc.setDisplay(sCalc.mrc()); + break; + default: + break; + } + break; + case 19: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a number: "); + cfcalc.setDisplay(userinput); + } + userinput = Console.getDoubleInput("Enter a number to see what percent of " + cfcalc.getDisplayValue() + " it is : "); + cfcalc.percentage(userinput); + System.out.println("= "+ cfcalc.getDisplayValue()+"%"); + + case 20: + if (!isdiplayval) { + userinput = Console.getDoubleInput("Enter a decimal to turn to percent: "); + cfcalc.setDisplay(userinput); + } + cfcalc.decimalToPercentage(); + System.out.println("= "+ cfcalc.getDisplayValue()+"%"); + default: + + break; + } } } diff --git a/src/main/java/com/zipcodewilmington/scientificcalculator/ScientificCalc.java b/src/main/java/com/zipcodewilmington/scientificcalculator/ScientificCalc.java new file mode 100644 index 0000000..89a6217 --- /dev/null +++ b/src/main/java/com/zipcodewilmington/scientificcalculator/ScientificCalc.java @@ -0,0 +1,190 @@ +package com.zipcodewilmington.scientificcalculator; + +public class ScientificCalc { + Double memvalue; + String DisplayMode; + int modeIndex; + boolean isDegrees; + + + public ScientificCalc(){ + memvalue = 0.0; + DisplayMode = "decimal"; + modeIndex = 0; + isDegrees = false; + } + + public void switchDisplayMode(){ + if(modeIndex == 3){ + modeIndex = 0; + }else{ + modeIndex++; + } + + switch (modeIndex) { + case 0: + DisplayMode = "decimal"; + System.out.println("set to:" + DisplayMode); + break; + case 1: + DisplayMode = "hexadecimal"; + System.out.println("set to:" + DisplayMode); + break; + case 2: + DisplayMode = "binary"; + System.out.println("set to:" + DisplayMode); + break; + case 3: + DisplayMode = "octal"; + System.out.println("set to:" + DisplayMode); + break; + default: + break; + } + + } + + public String getDisplayMode(){ + return DisplayMode; + } + + public void switchDisplayMode(String s){ + switch (s.toLowerCase()) { + case "decimal": + modeIndex = 0; + DisplayMode = s; + break; + case "hexadecimal": + modeIndex = 1; + DisplayMode = s; + break; + case "binary": + modeIndex = 2; + DisplayMode = s; + break; + case "octal": + modeIndex = 3; + DisplayMode = s; + break; + default: + System.out.println(s + " is not valid. Setting to decimal mode\n"); + modeIndex = 0; + DisplayMode = "decimal"; + break; + } + + } + + public void memmoryFunctions(double curValue, String memoryFunction){ + switch (memoryFunction.toLowerCase()) { + case "m+": + memvalue = curValue; + break; + case "mc": + memvalue = 0.0; + System.out.println("memory reset\n"); + break; + case "mrc": + System.out.println("value in memory: "+memvalue); + default: + break; + } + } + + public Double mrc(){ + return memvalue; + } + + public double sine(Double x){ + if(isDegrees){ + return Math.sin(Math.toRadians(x)); + }else{ + return Math.sin(x); + } + } + public double cosine(Double x){ + if(isDegrees){ + return Math.cos(Math.toRadians(x)); + }else{ + return Math.cos(x); + } + } + public double tangent(Double x){ + if(isDegrees){ + return Math.tan(Math.toRadians(x)); + }else{ + return Math.tan(x); + } + } + public double inverseSine(Double x){ + if(isDegrees){ + return Math.toDegrees(Math.asin(x)); + }else{ + return Math.asin(x); + } +} +public double inverseCosine(Double x){ + if(isDegrees){ + return Math.toDegrees(Math.acos(x)); + }else{ + return Math.acos(x); + } +} +public double inverseTangent(Double x){ + if(isDegrees){ + return Math.toDegrees(Math.atan(x)); + }else{ + return Math.atan(x); + } +} + + public void switchUnitsMode(){ + if(isDegrees){ + System.out.println("set to radians"); + isDegrees = false; + }else{ + System.out.println("set to degrees"); + isDegrees = true; + } + } + + public void switchUnitsMode(String s){ + if(s.toLowerCase() == "degree"){ + System.out.println("set to degrees"); + isDegrees = true; + }else if (s.toLowerCase() == "radians"){ + System.out.println("set to radians"); + isDegrees = false; + }else{ + System.out.println("invalid input defaulted to radians"); + isDegrees = false; + } + } + + public double log(Double x){ + return Math.log10(x); + } + + public double inverseLog(Double x){ + return Math.pow(10,x); + } + + public double naturalLog(Double x){ + return Math.log(x); + } + public double inverseNaturalLog(Double x){ + return Math.exp(x); + } + + public double factorial(Double x){ + return factorialFunction(x); + } + + public Double factorialFunction(Double x){ + if(x<=1) + return 1.0; + + return x * factorialFunction(x-1); + } + +} diff --git a/src/test/java/com/zipcodewilmington/scientific_calculator/TestMainApplication.java b/src/test/java/com/zipcodewilmington/scientific_calculator/TestMainApplication.java index 94e8d98..bd127dd 100644 --- a/src/test/java/com/zipcodewilmington/scientific_calculator/TestMainApplication.java +++ b/src/test/java/com/zipcodewilmington/scientific_calculator/TestMainApplication.java @@ -1,7 +1,145 @@ package com.zipcodewilmington.scientific_calculator; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.Before; + +import com.zipcodewilmington.scientificcalculator.CoreFeatures; + /** * Created by leon on 2/9/18. */ public class TestMainApplication { + + private CoreFeatures calculator; + + //set delta for comparisons + //assert equals (double expected, double actual, double delta) + private static final double DELTA =1e-6; + + @Before + public void setUp() { + calculator=new CoreFeatures(); + + } + + @Test + //Display initial + public void testInitialDisplay() { + assertEquals (0.0,calculator.getDisplayValue(),DELTA); + } + + @Test + //Display clear + public void testClear() { + calculator.setDisplay(100); + calculator.clear(); + assertEquals(0.0,calculator.getDisplayValue(),DELTA); + + } + + @Test + //Display + public void testSetDisplay (){ + calculator.setDisplay(182); + assertEquals(182,calculator.getDisplayValue(),DELTA); + + } + + @Test + //addition + public void testAdd() { + calculator.add(10); + assertEquals(10, calculator.getDisplayValue(),DELTA); + calculator.add(5); + assertEquals(15, calculator.getDisplayValue(), DELTA); + } + + @Test + //subtraction + public void testSubtract() { + calculator.setDisplay(10); + calculator.subtract(5); + assertEquals(5.0,calculator.getDisplayValue(),DELTA); + + } + + @Test + //multiplication + public void testMultiplication() { + calculator.setDisplay(5); + calculator.multiply(5); + assertEquals(25,calculator.getDisplayValue(),DELTA); + + } + + @Test + //division + public void testDivision() { + calculator.setDisplay(20); + calculator.divide(5); + assertEquals(4.0,calculator.getDisplayValue(),DELTA); + + } + + @Test + //square + public void testSquare() { + calculator.setDisplay(5); + calculator.square(); + assertEquals(25.0,calculator.getDisplayValue(),DELTA); + + } + + @Test + //square root + public void testRoot() { + calculator.setDisplay(25); + calculator.squareRoot(); + assertEquals(5.0,calculator.getDisplayValue(),DELTA); + } + + @Test + //exponent + public void testExponent() { + calculator.setDisplay(3); + calculator.exponentiation(2); + assertEquals(9.0,calculator.getDisplayValue(),DELTA); + + } + + @Test + //inverse + public void testInverse() { + calculator.setDisplay(5); + calculator.inverse(); + assertEquals(0.20, calculator.getDisplayValue(),DELTA); + + } + + @Test + //invert sign + public void testInvertSign() { + calculator.setDisplay(10); + calculator.inverseSign(); + assertEquals(-10.0, calculator.getDisplayValue(),DELTA); + + } + @Test + //new feature percentage of a number + public void testPercentageOfNum() { + calculator.setDisplay(100); + calculator.percentage(50); + assertEquals(50.0, calculator.getDisplayValue(), DELTA); + } + + @Test + //new feature turn decimal into a percentage + public void testDecimalToPercent() { + calculator.setDisplay(0.50); + calculator.decimalToPercentage(); + assertEquals(50.0, calculator.getDisplayValue(),DELTA); + } + }