Quickpois0n
Quickpois0n

Reputation: 79

Calculate result after clicking an operator on calculator

I am building a simple calculator exercise and I have been stucked on it for over a week, I am trying to concat results (a pair of numbers) on the calculator just by pressing the operator button.

I want, for example, to operate 2 + 4 * 5 / 15: every time the user presses an operator (2 + 4 then press 'x' and get a result stored on the previous number variable then multiply by 5 and calculate by the previous result and so on) but I don't know how to do it, my logic says that this part of the code should work but it doesn't.

if (!isNaN(previousNum)) { previousNum = currentNum; displayPrevResult.textContent = operate(operator, previousNum, currentNum); }

At this point I would like to know how to implement it (I have not added functionality to the equal, clear and decimal yet until I fix this "issue"). I'm a beginner and this last week I have been thinking on several ways to do it but none of them worked.

Thank you.

/* PSEUDO:

    CREATE A VARIABLE TO STORE THE CURRENT NUMBER, PREVIOUS NUMBER AND OPERATE SYMBOL.

    WHEN CLICK A NUMBER STORES IT IN A CURRENT NUMBER VARIABLE.

    WHEN CLICKING OPERATOR AND SELECT A SECOND NUMBER REPLACES CURRENT NUMBER WITH NEW NUMBER
    AND STORES OLD NUMBER IN THE PREVIOUS NUMBER VARIABLE.

    WHEN CLICKING OPERATOR AGAIN IT OPERATES THE CURRENT NUMBER BY THE PREVIOUS NUMBER, 
    STORES THE RESULT IN THE PREVIOUS NUMBER VARIABLE AND EMPTY THE CURRENT NUMBER VARIABLE.

    WHEN PRESSING EQUAL BUTTON OPERATES CURRENT NUMBER BY PREVIOUS NUMBER AND STORES IT IN PREVIOUS NUMBER VARIABLE.
    
        > IF CURRENT NUMBER AND PREVIOUS NUMBER VARIABLE HAS A NUMBER THEN EQUAL BUTTON OPERATES
        > IF NOT, EQUAL BUTTON DOES NOT WORK.

    IF DIVIDE CURRENT NUMBER BY 0 THEN THROWS AN ERROR.

*/





const displayPrevResult = document.querySelector('.prev-result');
const displayCurrentResult = document.querySelector('.current-result');
const equal = document.querySelector('.equal');
const decimal = document.querySelector('.decimal');
const clear = document.querySelector('.clear');

const numberBtn = document.querySelectorAll('.number');
const operatorBtn = document.querySelectorAll('.operator');

let currentNum = '';
let previousNum = '';
let operator = '';


numberBtn.forEach((button) => {
    button.addEventListener('click', (event) => {
        getNum(event.target.textContent);
    });
});

operatorBtn.forEach((button) => {
    button.addEventListener('click', (event) => {
        getOp(event.target.textContent);
    });
});

function getNum(num) {
    currentNum += num;
    currentNum = parseFloat(currentNum);
    displayCurrentResult.textContent = currentNum;
}

function getOp(op) {
    operator = op;
    previousNum = currentNum;
    displayPrevResult.textContent = previousNum + ' ' + operator;
    currentNum = '';

    if (!isNaN(previousNum)) {
        previousNum = currentNum;
        displayPrevResult.textContent = operate(operator, previousNum, currentNum);
    }    
}

function operate(op, a, b) {
    switch(op) {
        case '+':
            return add(a, b);
        break;
        case '-':
            return subtract(a, b);
        break;
        case 'x':
            return multiply(a, b);
        break;
        case '÷':
            return divide(a, b);
        default:
    }
}

//Operating functions
function add(a, b) {
    return a + b;
}

function subtract(a, b) {
    return a - b;
}

function multiply(a, b) {
    return a * b;
}

function divide(a, b) {
    return a / b;
}
body {
    width: 100vw;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}

.calcContainer {
    background: linear-gradient(276deg, #40a179, #77cea9);
    padding: 1em;
    border-radius: 5px;
    border: 1px solid #000;
}

button {
    padding: 1em;
    margin: 0.1em;
    width: 40px;
    background: #a2ffaf;
    border: 1px solid #fff;
    border-radius: 3px;
    cursor: pointer;
}

button:hover {
    background: #72e782;
}

.clr {
    background: #87e4bd;
}

.clr:hover {
    background: #53ad88;
}

.clear {
    margin: 0em 0.1em 0.5em 0.5em;
    padding: 0;
}

.output-clear-container {
    display: flex;
}

.output {
    flex-grow: 1;
    height: 40px;
    background: #c2fcca;
    border-radius: 5px;
    border: 1px solid #fff;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-content: flex-end;
    padding-right: 0.5em;
    margin-bottom: 0.5em;
}

.par {
    margin-bottom: 0.3em;
}

.prev-result {
    font-size: 14px;
    padding-bottom: 0.3em;
    color:#40a179;
}

.current-result {
    font-size: 18px;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="styles.css">
    <script src="main.js" defer></script>
    <title>Calculator</title>
</head>
<body>
    <div class="calcContainer">
        <div class="output-clear-container">
            <div class="output">
                <div class="prev-result"></div>
                <div class="current-result">0</div>
            </div>
            <button class="clear">AC</button>
        </div>
            <div class="par">
                <button class="number">7</button>
                <button class="number">8</button>
                <button class="number">9</button>
                <button class="operator clr">÷</button>
            </div>
            <div class="par">
                <button class="number">4</button>
                <button class="number">5</button>
                <button class="number">6</button>
                <button class="operator clr">x</button>
            </div>
            <div class="par">
                <button class="number">1</button>
                <button class="number">2</button>
                <button class="number">3</button>
                <button class="operator clr">-</button>
            </div>
            <div class="par">
                <button class="decimal clr">.</button>
                <button class="number">0</button>
                <button class="equal clr">=</button>
                <button class="operator clr">+</button>
            </div>
    </div>
</body>
</html>

Upvotes: 0

Views: 1179

Answers (2)

Jay Speights
Jay Speights

Reputation: 71

I've made some small changes to your code that I believe captures the behavior you are looking for. You were somewhat close, and this isn't an easy task, so don't get discouraged.

I switched some of the variables to be null by default. It will probably be easier to track whether or not they have had values set that way. isNan returns false for an empty string, so that was one source of error for your code

let currentNum = '';
let previousNum = null;
let operator = null;

What you were doing was correct in getOp, but it wasn't quite in the right order. I have revised it below.

function getOp(op) {

    if (operator == null) { // Is this the first time we have pressed operator ?
        previousNum = currentNum; // then our current number is the current result
    } else if (previousNum != null){ // Do we already have a number and operator in the stack ?
        previousNum = operate(operator, previousNum, currentNum); // calculate the result
    }

    displayPrevResult.textContent = previousNum + ' ' + op;
    operator = op;
    currentNum = '';
    displayCurrentResult.innerHTML = '0';
}

With those two changes, it should be working in at least some capacity

Upvotes: 1

Naoe
Naoe

Reputation: 1219

A lot of stuff is wrong with this code. =/

For instance, here you are setting a variable(currentNum) to an empty string. And than right after you are trying to use it as a number to do arithmetic.

currentNum = '';

if (!isNaN(previousNum)) {
  previousNum = currentNum;
  displayPrevResult.textContent = operate(operator, previousNum, currentNum);
}  

Tip! Try not to mix numbers and strings on the same variables.

Another tip is to make sure you convert input fields to numbers before doing arithmetic.

Example:
2 + 2 = 4
'2' + '2' = '22'

Upvotes: 1

Related Questions