Created
November 28, 2009 21:28
-
-
Save raulbrito/244657 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package calculator; | |
public class CalculatorController { | |
private final CalculatorModel model; | |
private Calculation calculation; | |
public CalculatorController(CalculatorModel model, Calculation calculation) { | |
this.model = model; | |
this.calculation = calculation; | |
} | |
public void push(char charAt) { | |
int number; | |
if (SignMapper.isSign(charAt)) { | |
calculation.sign(SignMapper.getSign(charAt)); | |
} else { | |
number = Numeric.getNumeric(charAt); | |
calculation.number(number); | |
} | |
String displayString = transformValue(calculation.getValue()); | |
model.setDisplay(displayString); | |
} | |
private String transformValue(double currentValue) { | |
String stringValue = "" + currentValue; | |
if (Math.floor(currentValue) != currentValue) { | |
return stringValue; | |
} else { | |
return stringValue.substring(0, stringValue.length() - 1); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package calculator; | |
import calculator.CalculatorController; | |
import calculator.CalculatorModel; | |
import junit.framework.TestCase; | |
public class CalculatorControllerTest extends TestCase { | |
CalculatorModel model = new CalculatorModel(); | |
Calculation calculation = new StandardCalculation(); | |
CalculatorController controller; | |
public void setUp() { | |
controller = new CalculatorController(model, calculation); | |
} | |
public void testItShouldInitializeToZero() throws Exception { | |
controller.push('C'); | |
assertEquals("0.", model.getDisplay()); | |
} | |
public void testItShouldConcatenateTwoNumberPresses() { | |
controller.push('1'); | |
controller.push('2'); | |
assertEquals("12.", model.getDisplay()); | |
} | |
public void testItShouldConcatenateThreeNumberPresses() { | |
bulkPush("369"); | |
assertEquals("369.", model.getDisplay()); | |
} | |
public void testItShouldSupportDecimalPoint() { | |
bulkPush("4.7"); | |
assertEquals("4.7", model.getDisplay()); | |
} | |
public void testItShouldNotCareAboutSecondDecimalPoint() { | |
bulkPush("4.7.."); | |
assertEquals("4.7", model.getDisplay()); | |
} | |
public void testDoPlus() { | |
bulkPush("4+5="); | |
assertEquals("9.", model.getDisplay()); | |
} | |
public void testDoMinus() { | |
bulkPush("2-4="); | |
assertEquals("-2.", model.getDisplay()); | |
} | |
public void testDoMultiply() { | |
bulkPush("2*4="); | |
assertEquals("8.", model.getDisplay()); | |
} | |
public void testDoDivision() { | |
bulkPush("2/4="); | |
assertEquals("0.5", model.getDisplay()); | |
} | |
public void testPutSignal() { | |
controller.push('2'); | |
controller.push('±'); | |
assertEquals("-2.", model.getDisplay()); | |
} | |
public void testDoDivisionWithOtherSymbol() { | |
bulkPush("2÷4="); | |
assertEquals("0.5", model.getDisplay()); | |
} | |
public void testGetValueAfterSign() { | |
controller.push('2'); | |
controller.push('+'); | |
assertEquals("2.", model.getDisplay()); | |
} | |
public void testDoSquareRoot() { | |
bulkPush("4√2="); | |
assertEquals("2.", model.getDisplay()); | |
} | |
public void testDoPower() { | |
bulkPush("4^4="); | |
assertEquals("256.", model.getDisplay()); | |
} | |
private void bulkPush(String push) { | |
char[] list = push.toCharArray(); | |
for (int i = 0; i < list.length; i++) { | |
controller.push(list[i]); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class StandardCalculation implements Calculation { | |
private double leftValue = 0; | |
private double currentValue = 0; | |
private double decimalLevel = 0; | |
private CalculationState operationTerm = CalculationState.LEFT_TERM; | |
private Sign operationType; | |
private static final int INTEGER_PART = 10; | |
private static final double DECIMAL_PART = 0.1; | |
@Override | |
public double getValue() { | |
return currentValue; | |
} | |
@Override | |
public void number(int number) { | |
double doubleNumber = number; | |
if (operationTerm == CalculationState.OPERATION) { | |
currentValue = 0; | |
operationTerm = CalculationState.RIGHT_TERM; | |
} | |
if (isDecimal()) { | |
currentValue *= INTEGER_PART; | |
} else { | |
doubleNumber = decimalLevel * doubleNumber; | |
decimalLevel *= DECIMAL_PART; | |
} | |
if (isNegative()) { | |
currentValue -= doubleNumber; | |
} else { | |
currentValue += doubleNumber; | |
} | |
} | |
private boolean isNegative() { | |
return currentValue < 0; | |
} | |
private boolean isDecimal() { | |
return decimalLevel == 0; | |
} | |
@Override | |
public void sign(Sign symbol) { | |
switch(symbol) { | |
case CLEAR: | |
resetInformation(); | |
break; | |
case DOT: | |
decimalLevel = DECIMAL_PART; | |
break; | |
case PLUS: | |
case MINUS: | |
case MULTIPLY: | |
case DIVISION: | |
case ROOT: | |
case POWER: | |
if (isLeftTerm()) { | |
changeToOperationTerm(symbol); | |
} | |
if (isRightTerm()) { | |
this.sign(Sign.EQUALS); | |
} | |
break; | |
case EQUALS: | |
if (isNotEqualsTerm()) { | |
calculateResult(); | |
currentValue = leftValue; | |
operationTerm = CalculationState.EQUALS; | |
} | |
break; | |
case SIGNAL: | |
if (isLeftTerm() || isRightTerm()) { | |
currentValue *= -1; | |
} | |
break; | |
default: | |
throw new UnsupportedOperationException(); | |
} | |
} | |
private boolean isRightTerm() { | |
return operationTerm == CalculationState.RIGHT_TERM; | |
} | |
private void resetInformation() { | |
leftValue = 0; | |
currentValue = 0; | |
operationTerm = CalculationState.LEFT_TERM; | |
decimalLevel = 0; | |
} | |
private void calculateResult() { | |
if (operationType == Sign.PLUS) { | |
leftValue += currentValue; | |
} | |
if (operationType == Sign.MINUS) { | |
leftValue -= currentValue; | |
} | |
if (operationType == Sign.MULTIPLY) { | |
leftValue *= currentValue; | |
} | |
if (operationType == Sign.DIVISION) { | |
leftValue /= currentValue; | |
} | |
if (operationType == Sign.ROOT) { | |
leftValue = Math.pow(leftValue, 1.0/currentValue); | |
} | |
if (operationType == Sign.POWER) { | |
leftValue = Math.pow(leftValue, currentValue); | |
} | |
} | |
private boolean isNotEqualsTerm() { | |
return operationTerm != CalculationState.EQUALS; | |
} | |
private void changeToOperationTerm(Sign operation) { | |
operationType = operation; | |
leftValue = currentValue; | |
decimalLevel = 0; | |
operationTerm = CalculationState.OPERATION; | |
} | |
private boolean isLeftTerm() { | |
return operationTerm == CalculationState.LEFT_TERM; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment