Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#2PlaysAMonth]: Calculator #944

Merged
merged 13 commits into from
Feb 27, 2023
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"json-graphql-parser": "^0.1.8",
"jspdf": "^2.5.1",
"lodash": "^4.17.21",
"mathjs": "^11.5.1",
"node-sass": "^8.0.0",
"p5": "^1.5.0",
"react": "^18.0.0",
Expand Down
27 changes: 27 additions & 0 deletions src/plays/simple-calculator/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Simple Calculator
suryanshsoni120 marked this conversation as resolved.
Show resolved Hide resolved

I will create a Calculator which can perform basic arithmetic operations. The application uses math.js library to perform the calculations.

## Play Demographic

- Language: js
- Level: Beginner

## Creator Information

- User: suryanshsoni120
- Gihub Link: https://github.com/suryanshsoni120
- Blog:
- Video:

## Implementation Details

Update your implementation idea and details here

## Consideration

Update all considerations(if any)

## Resources

Update external resources(if any)
22 changes: 22 additions & 0 deletions src/plays/simple-calculator/SimpleCalculator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import PlayHeader from 'common/playlists/PlayHeader';
import React from 'react';
import Calculator from './components/Calculator';

// WARNING: Do not change the entry componenet name
function SimpleCalculator(props) {
// Your Code Start below.
return (
<>
<div className="play-details">
<PlayHeader play={props} />
<div className="play-details-body suri-calci">
{/* Your Code Starts Here */}
<Calculator />
{/* Your Code Ends Here */}
</div>
</div>
</>
);
}

export default SimpleCalculator;
106 changes: 106 additions & 0 deletions src/plays/simple-calculator/components/Buttons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import React from 'react';
import '../styles/Buttons.css';
// import CALCULATOR_BUTTONS from "./CalculatorButtons";

const Buttons = ({ inputHandler, clearInput, backspace, changePlusMinus, calculateAns }) => {
document.addEventListener('keydown', function (event) {
if (event.key === 'Enter') {
event.preventDefault();
document.getElementById('equalbtn').click();
}
});

return (
<div className="suri-calci-btn">
<button className="btn exp" onClick={inputHandler}>
^
</button>
<button className="btn exp" onClick={inputHandler}>
(
</button>
<button className="btn exp" onClick={inputHandler}>
)
</button>
<button className="btn exp" onClick={inputHandler}>
</button>
<button className="btn exp" onClick={inputHandler}>
x<sup>2</sup>
</button>
<button className="btn clr" onClick={clearInput}>
AC
</button>
<button className="btn clr" onClick={backspace}>
</button>
<button className="btn exp" onClick={inputHandler}>
log
</button>
<button className="btn exp" onClick={inputHandler}>
÷
</button>
<button className="btn exp" onClick={inputHandler}>
%
</button>
<button className="btn" onClick={inputHandler}>
7
</button>
<button className="btn" onClick={inputHandler}>
8
</button>
<button className="btn" onClick={inputHandler}>
9
</button>
<button className="btn exp" onClick={inputHandler}>
x
</button>
<button className="btn exp" onClick={inputHandler}>
x<sup>3</sup>
</button>
<button className="btn" onClick={inputHandler}>
4
</button>
<button className="btn" onClick={inputHandler}>
5
</button>
<button className="btn" onClick={inputHandler}>
6
</button>
<button className="btn exp" onClick={inputHandler}>
-
</button>
<button className="btn exp" onClick={inputHandler}>
<sup>3</sup>√
</button>
<button className="btn" onClick={inputHandler}>
1
</button>
<button className="btn" onClick={inputHandler}>
2
</button>
<button className="btn" onClick={inputHandler}>
3
</button>
<button className="btn exp" onClick={inputHandler}>
+
</button>
<button className="btn exp" onClick={inputHandler}>
!
</button>
<button className="btn exp" onClick={changePlusMinus}>
±
</button>
<button className="btn" onClick={inputHandler}>
0
</button>
<button className="btn exp" onClick={inputHandler}>
.
</button>
<button className="btn exp equal" id="equalbtn" onClick={calculateAns}>
=
</button>
</div>
);
};

export default Buttons;
149 changes: 149 additions & 0 deletions src/plays/simple-calculator/components/Calculator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import React, { useState } from 'react';
import Display from './Display';
import Buttons from './Buttons';
import '../styles/Calculator.css';
import { evaluate, round } from 'mathjs';

function Calculator() {
const [input, setInput] = useState('');
const [answer, setAnswer] = useState('');

// input
const inputHandler = (event) => {
if (answer === 'Invalid Input!!') return;
let val = event.target.innerText;

if (val === 'x2') val = '^2';
else if (val === 'x3') val = '^3';
else if (val === '3√') val = '^(1÷3)';
else if (val === 'log') val = 'log(';

let str = input + val;
if (str.length > 14) return;

if (answer !== '') {
setInput(answer + val);
setAnswer('');
} else setInput(str);
// setInput(str);
};

// Clear screen
const clearInput = () => {
setInput('');
setAnswer('');
};

// check brackets are balanced or not
const checkBracketBalanced = (expr) => {
let stack = [];
for (let i = 0; i < expr.length; i++) {
let x = expr[i];
if (x === '(') {
stack.push(x);

continue;
}

if (x === ')') {
if (stack.length === 0) return false;
else stack.pop();
}
}

return stack.length === 0;
};

// calculate final answer
const calculateAns = () => {
if (input === '') return;
let result = 0;
let finalexpression = input;
// finalexpression = input.replaceAll("^", "**"); //for eval()
finalexpression = finalexpression.replaceAll('x', '*');
finalexpression = finalexpression.replaceAll('÷', '/');

// evaluate square root
let noSqrt = input.match(/√[0-9]+/gi);

if (noSqrt !== null) {
let evalSqrt = input;
for (let i = 0; i < noSqrt.length; i++) {
evalSqrt = evalSqrt.replace(noSqrt[i], `sqrt(${noSqrt[i].substring(1)})`);
}
finalexpression = evalSqrt;
}

try {
// check brackets are balanced or not
if (!checkBracketBalanced(finalexpression)) {
const errorMessage = { message: 'Unbalanced ()!' };

throw errorMessage;
}
result = evaluate(finalexpression); // mathjs
} catch (error) {
result = error.message === 'Unbalanced ()!' ? 'Unbalanced ()!' : 'Invalid Input!!'; // error.message;
}
isNaN(result) ? setAnswer(result) : setAnswer(round(result, 3));
};

// remove last character
const backspace = () => {
if (answer !== '') {
setInput(answer.toString().slice(0, -1));
setAnswer('');
} else setInput((prev) => prev.slice(0, -1));
};

// change prefix of expression
const changePlusMinus = () => {
// need to change for answer
if (answer === 'Invalid Input!!') return;
else if (answer !== '') {
let ans = answer.toString();
if (ans.charAt(0) === '-') {
let plus = '+';
setInput(plus.concat(ans.slice(1, ans.length)));
} else if (ans.charAt(0) === '+') {
let minus = '-';
setInput(minus.concat(ans.slice(1, ans.length)));
} else {
let minus = '-';
setInput(minus.concat(ans));
}
setAnswer('');
} else {
if (input.charAt(0) === '-') {
let plus = '+';
setInput((prev) => plus.concat(prev.slice(1, prev.length)));
} else if (input.charAt(0) === '+') {
let minus = '-';
setInput((prev) => minus.concat(prev.slice(1, prev.length)));
} else {
let minus = '-';
setInput((prev) => minus.concat(prev));
}
}
};

return (
<>
<h1 className="text-center my-4 py-4">Calculations Made Easy!!!</h1>
<div className="suri-calc-container">
<div className="suri-calc-main">
<Display answer={answer} input={input} setInput={setInput} />
<Buttons
backspace={backspace}
calculateAns={calculateAns}
changePlusMinus={changePlusMinus}
clearInput={clearInput}
inputHandler={inputHandler}
/>
</div>
</div>
</>
);
}

export default Calculator;
50 changes: 50 additions & 0 deletions src/plays/simple-calculator/components/Display.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react';
import '../styles/Display.css';

const Display = ({ input, setInput, answer }) => {
const onChangeTagInput = (event) => {
const change = /^[!%(-+\x2D-9^glox\xF7\u221A]+$/;

if (event.target.value === '' || change.test(event.target.value)) {
setInput(event.target.value);
}
};

return (
<>
<div className="suri-calc-display">
{answer === '' ? (
<>
<input
autoComplete="off"
className="suri-calc-input"
maxLength={12}
name="input"
placeholder="0"
style={{ padding: '29px' }}
type="text"
value={input}
// disabled
onChange={onChangeTagInput}
/>
</>
) : (
<>
<input
disabled
className="suri-calc-value"
maxLength={12}
name="input"
placeholder="0"
type="text"
value={input}
/>
<input disabled className="suri-calc-input" name="value" type="text" value={answer} />
</>
)}
</div>
</>
);
};

export default Display;
Binary file added src/plays/simple-calculator/cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading