diff --git a/src/pages/activities/Calculator.js b/src/pages/activities/Calculator.js
index 8583bf2..91cfe05 100644
--- a/src/pages/activities/Calculator.js
+++ b/src/pages/activities/Calculator.js
@@ -15,7 +15,6 @@ class Calculator extends React.Component {
let op = [];
let temp = this.state.screenValue1.toString();
if(a === "=") {
- console.log(temp)
for (let j = 0; j < temp.length; j++) {
if(temp[j] !== '/' && temp[j] !== 'x' && temp[j] !== '-' && temp[j] !== '+') {
r = `${r}${temp[j]}`
@@ -26,7 +25,6 @@ class Calculator extends React.Component {
r = ''
}
}
- console.log(arr)
arr.push(r)
if(arr[0] === '' && op[0] === '-') {
arr[1]=`${op[0]}${arr[1]}`
@@ -36,13 +34,10 @@ class Calculator extends React.Component {
if(arr[0] === '') {
arr[0] = 0
}
- console.log(arr)
r = '';
for(let x1 = 0; x1 < arr.length; x1++) {
arr[x1] = parseFloat(arr[x1])
}
- console.log(arr)
- console.log(op)
for(let x3 = 0; x3 < arr.length; x3++) {
if(isNaN(arr[x3])) {
arr[x3+1] = -arr[x3+1]
@@ -53,16 +48,35 @@ class Calculator extends React.Component {
if(op.length === 0){
return
}
+
+ // Two-pass algorithm for order of operations (PEMDAS/BODMAS)
+ // First pass: Process multiplication and division (left to right)
for(let b = 0; b < op.length; b++) {
- if(op[b] === '/') {r = arr[0] / arr[1]; arr.shift(); arr[0] = r}
- if(op[b] === 'x') {r = arr[0] * arr[1]; arr.shift(); arr[0] = r}
- if(op[b] === '-') {r = arr[0] - arr[1]; arr.shift(); arr[0] = r}
- if(op[b] === '+') {r = arr[0] + arr[1]; arr.shift(); arr[0] = r}
- console.log(r)
+ if(op[b] === '/' || op[b] === 'x') {
+ if(op[b] === '/') {
+ r = arr[b] / arr[b+1];
+ } else {
+ r = arr[b] * arr[b+1];
+ }
+ // Replace the two operands with the result
+ arr.splice(b, 2, r);
+ // Remove the operator
+ op.splice(b, 1);
+ // Adjust index since we removed an element
+ b--;
+ }
}
- console.log(r)
- if(this.state.screenValue1[0] === 0) {
- console.log('doin something funny')
+
+ // Second pass: Process addition and subtraction (left to right)
+ for(let b = 0; b < op.length; b++) {
+ if(op[b] === '-') {
+ r = arr[b] - arr[b+1];
+ } else if(op[b] === '+') {
+ r = arr[b] + arr[b+1];
+ }
+ arr.splice(b, 2, r);
+ op.splice(b, 1);
+ b--;
}
r = r.toString()
while(r.length > 15) {
diff --git a/src/pages/activities/__tests__/Calculator.test.js b/src/pages/activities/__tests__/Calculator.test.js
new file mode 100644
index 0000000..705560b
--- /dev/null
+++ b/src/pages/activities/__tests__/Calculator.test.js
@@ -0,0 +1,250 @@
+import React from 'react';
+import { render, screen, fireEvent } from '@testing-library/react';
+import Calculator from '../Calculator';
+
+describe('Calculator Order of Operations', () => {
+ describe('PEMDAS/BODMAS - Multiplication and Division before Addition and Subtraction', () => {
+ test('should multiply before adding: 2 + 3 × 4 = 14', () => {
+ render();
+
+ // Clear calculator first
+ fireEvent.click(screen.getByText('AC'));
+
+ // Enter: 2 + 3 × 4 =
+ fireEvent.click(screen.getByText('2'));
+ fireEvent.click(screen.getByText('+'));
+ fireEvent.click(screen.getByText('3'));
+ fireEvent.click(screen.getByText('x'));
+ fireEvent.click(screen.getByText('4'));
+ fireEvent.click(screen.getByText('='));
+
+ const display = screen.getByText('14');
+ expect(display).toBeInTheDocument();
+ });
+
+ test('should divide before subtracting: 10 - 8 / 2 = 6', () => {
+ const { container } = render();
+
+ fireEvent.click(screen.getByText('AC'));
+
+ // Enter: 10 - 8 / 2 =
+ fireEvent.click(screen.getByText('1'));
+ fireEvent.click(screen.getByText('0'));
+ fireEvent.click(screen.getByText('-'));
+ fireEvent.click(screen.getByText('8'));
+ fireEvent.click(screen.getByText('/'));
+ fireEvent.click(screen.getByText('2'));
+ fireEvent.click(screen.getByText('='));
+
+ const display = container.querySelector('#display');
+ expect(display).toHaveTextContent('6');
+ });
+
+ test('should multiply before adding (reversed): 5 + 2 × 3 = 11', () => {
+ render();
+
+ fireEvent.click(screen.getByText('AC'));
+
+ // Enter: 5 + 2 × 3 =
+ fireEvent.click(screen.getByText('5'));
+ fireEvent.click(screen.getByText('+'));
+ fireEvent.click(screen.getByText('2'));
+ fireEvent.click(screen.getByText('x'));
+ fireEvent.click(screen.getByText('3'));
+ fireEvent.click(screen.getByText('='));
+
+ const display = screen.getByText('11');
+ expect(display).toBeInTheDocument();
+ });
+
+ test('should divide before subtracting: 12 - 3 / 3 = 11', () => {
+ render();
+
+ fireEvent.click(screen.getByText('AC'));
+
+ // Enter: 12 - 3 / 3 =
+ fireEvent.click(screen.getByText('1'));
+ fireEvent.click(screen.getByText('2'));
+ fireEvent.click(screen.getByText('-'));
+ fireEvent.click(screen.getByText('3'));
+ fireEvent.click(screen.getByText('/'));
+ fireEvent.click(screen.getByText('3'));
+ fireEvent.click(screen.getByText('='));
+
+ const display = screen.getByText('11');
+ expect(display).toBeInTheDocument();
+ });
+ });
+
+ describe('Multiple operations with mixed precedence', () => {
+ test('should handle: 2 + 3 × 4 - 5 = 9', () => {
+ const { container } = render();
+
+ fireEvent.click(screen.getByText('AC'));
+
+ // Enter: 2 + 3 × 4 - 5 =
+ fireEvent.click(screen.getByText('2'));
+ fireEvent.click(screen.getByText('+'));
+ fireEvent.click(screen.getByText('3'));
+ fireEvent.click(screen.getByText('x'));
+ fireEvent.click(screen.getByText('4'));
+ fireEvent.click(screen.getByText('-'));
+ fireEvent.click(screen.getByText('5'));
+ fireEvent.click(screen.getByText('='));
+
+ const display = container.querySelector('#display');
+ expect(display).toHaveTextContent('9');
+ });
+
+ test('should handle: 5 + 2 × 3 - 4 / 2 = 9', () => {
+ const { container } = render();
+
+ fireEvent.click(screen.getByText('AC'));
+
+ // Enter: 5 + 2 × 3 - 4 / 2 =
+ fireEvent.click(screen.getByText('5'));
+ fireEvent.click(screen.getByText('+'));
+ fireEvent.click(screen.getByText('2'));
+ fireEvent.click(screen.getByText('x'));
+ fireEvent.click(screen.getByText('3'));
+ fireEvent.click(screen.getByText('-'));
+ fireEvent.click(screen.getByText('4'));
+ fireEvent.click(screen.getByText('/'));
+ fireEvent.click(screen.getByText('2'));
+ fireEvent.click(screen.getByText('='));
+
+ const display = container.querySelector('#display');
+ expect(display).toHaveTextContent('9');
+ });
+ });
+
+ describe('Same precedence operations (left to right)', () => {
+ test('should process left to right for same precedence: 10 - 5 - 2 = 3', () => {
+ const { container } = render();
+
+ fireEvent.click(screen.getByText('AC'));
+
+ // Enter: 10 - 5 - 2 =
+ fireEvent.click(screen.getByText('1'));
+ fireEvent.click(screen.getByText('0'));
+ fireEvent.click(screen.getByText('-'));
+ fireEvent.click(screen.getByText('5'));
+ fireEvent.click(screen.getByText('-'));
+ fireEvent.click(screen.getByText('2'));
+ fireEvent.click(screen.getByText('='));
+
+ const display = container.querySelector('#display');
+ expect(display).toHaveTextContent('3');
+ });
+
+ test('should handle division and multiplication left to right: 12 / 3 × 2 = 8', () => {
+ const { container } = render();
+
+ fireEvent.click(screen.getByText('AC'));
+
+ // Enter: 12 / 3 × 2 =
+ fireEvent.click(screen.getByText('1'));
+ fireEvent.click(screen.getByText('2'));
+ fireEvent.click(screen.getByText('/'));
+ fireEvent.click(screen.getByText('3'));
+ fireEvent.click(screen.getByText('x'));
+ fireEvent.click(screen.getByText('2'));
+ fireEvent.click(screen.getByText('='));
+
+ const display = container.querySelector('#display');
+ expect(display).toHaveTextContent('8');
+ });
+
+ test('should handle multiplication and division left to right: 2 × 6 / 3 = 4', () => {
+ const { container } = render();
+
+ fireEvent.click(screen.getByText('AC'));
+
+ // Enter: 2 × 6 / 3 =
+ fireEvent.click(screen.getByText('2'));
+ fireEvent.click(screen.getByText('x'));
+ fireEvent.click(screen.getByText('6'));
+ fireEvent.click(screen.getByText('/'));
+ fireEvent.click(screen.getByText('3'));
+ fireEvent.click(screen.getByText('='));
+
+ const display = container.querySelector('#display');
+ expect(display).toHaveTextContent('4');
+ });
+ });
+
+ describe('Edge cases and special scenarios', () => {
+ test('should handle decimal operations with order of operations: 5 + 2.5 × 2 = 10', () => {
+ const { container } = render();
+
+ fireEvent.click(screen.getByText('AC'));
+
+ // Enter: 5 + 2.5 × 2 =
+ fireEvent.click(screen.getByText('5'));
+ fireEvent.click(screen.getByText('+'));
+ fireEvent.click(screen.getByText('2'));
+ fireEvent.click(screen.getByText('.'));
+ fireEvent.click(screen.getByText('5'));
+ fireEvent.click(screen.getByText('x'));
+ fireEvent.click(screen.getByText('2'));
+ fireEvent.click(screen.getByText('='));
+
+ const display = container.querySelector('#display');
+ expect(display).toHaveTextContent('10');
+ });
+
+ test('should handle negative numbers: -5 + 3 × 2 = 1', () => {
+ const { container } = render();
+
+ fireEvent.click(screen.getByText('AC'));
+
+ // Enter: -5 + 3 × 2 =
+ fireEvent.click(screen.getByText('-'));
+ fireEvent.click(screen.getByText('5'));
+ fireEvent.click(screen.getByText('+'));
+ fireEvent.click(screen.getByText('3'));
+ fireEvent.click(screen.getByText('x'));
+ fireEvent.click(screen.getByText('2'));
+ fireEvent.click(screen.getByText('='));
+
+ const display = container.querySelector('#display');
+ expect(display).toHaveTextContent('1');
+ });
+ });
+
+ describe('Basic calculator functionality', () => {
+ test('should display initial value of 0', () => {
+ const { container } = render();
+ const display = container.querySelector('#display');
+ expect(display).toHaveTextContent('0');
+ });
+
+ test('should clear display when AC is clicked', () => {
+ const { container } = render();
+
+ // Enter some numbers
+ fireEvent.click(screen.getByText('5'));
+ fireEvent.click(screen.getByText('8'));
+
+ // Clear
+ fireEvent.click(screen.getByText('AC'));
+
+ const display = container.querySelector('#display');
+ expect(display).toHaveTextContent('0');
+ });
+
+ test('should handle simple addition: 5 + 3 = 8', () => {
+ const { container } = render();
+
+ fireEvent.click(screen.getByText('AC'));
+ fireEvent.click(screen.getByText('5'));
+ fireEvent.click(screen.getByText('+'));
+ fireEvent.click(screen.getByText('3'));
+ fireEvent.click(screen.getByText('='));
+
+ const display = container.querySelector('#display');
+ expect(display).toHaveTextContent('8');
+ });
+ });
+});
+