Overview
Refactor the calculator from the previous useState implementation to useReducer, maintaining all functionality and edge case handling.
Requirements
- Display the current expression as the user types.
- Evaluate mathematical expressions correctly when the equals button is pressed.
- Support the four basic operations: addition, subtraction, multiplication, and division.
- Allow decimal numbers and negative numbers.
- Prevent invalid inputs or sequences:
- The expression cannot start with
+, *, or /.
- The expression can start with
- to represent a negative number.
- Disallow consecutive operators except when using
- to indicate a negative number.
- Avoid multiple dots within the same number.
- Prevent evaluation when the last element is an operator or when the expression is empty.
- Handle negative numbers properly after any operator.
- Prevent more than two consecutive
- signs.
- Replace leading zeros when typing new numbers (e.g.,
03 → 3).
- Allow chaining of operations and continuous usage after evaluating a result:
- If a result is displayed and the user presses an operator, continue from that result.
- If a result is displayed and the user presses a number, start a new expression.
- Clear the display and reset the calculator when pressing
C.
Notes
- Implemented using useReducer instead of useState. Maintain all previous functionality and edge case handling from the prior calculator challenge.
- The display should show either the full expression or the result, depending on context.
- Expressions must update immediately as buttons are pressed.
- Consecutive operators must be handled gracefully (e.g., replacing the previous one if needed).
- Negative numbers after operators (e.g.,
5*-2) must be valid.
- The calculator should handle decimal precision correctly (round results to two decimals if needed).
- Clearing should reset both the expression and the result.
Tests
- basic sum operation
- more complex sum operation
- does not allow '+' as the first value
- does not allow '*' as the first value
- does not allow '/' as the first value
- allows '-' as the first value (negative numbers)
- allow negative numbers after any operator
- prevents more than two consecutive '-' and allows negative numbers correctly
- handle leading zeros correctly
- if there is a result and a number or operator is pressed
- prevent multiple dots in the same number
- prevent consecutive operators
- concatenate numbers/dots if the last element is a number
- prevent evaluating if the last element is an operator
- prevent evaluating if is empty
- clear