skip to Main Content

I am making a calculator for the FreeCodeCamp Project for Front End Development Libraries. I am stuck now with creating a function where I can use the "-" button also for negative values (e.g. 5*-5). I made it work with a +/- button, like on a normal calculator, but this doesn’t pass the test of FCC even though it works. They want you to use the "-" for both subtract and negative values.

How could I do that? I am stuck on it for 2 days now but have no idea how to solve it.

Here is the html code:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
<script>
 let  trailingResult = 0;
let operationOptions = ['divide', 'multiply', 'subtract','add'];
let workingOperation ="";

function updateDisplay(input) {
  let display = document.getElementById("display");

  if (display.innerHTML === "0" && operationOptions.indexOf(input) === -1) {
    if (input === 'decimal') {
      display.innerHTML = "0.";
    } else {
      display.innerHTML = input;
    }
  } else if (operationOptions.indexOf(input) >= 0){
    // dealing without initial operand
    if (workingOperation === "") {
      workingOperation = input;
      trailingResult = display.innerHTML;
      display.innerHTML = 0;
    } else if (operationOptions.indexOf(display.innerHTML.slice(-1)) >= 0) {
      workingOperation = input;
    }
    // dealing with a set operand
    else {
      trailingResult = calculate(trailingResult, display.innerHTML, workingOperation);
      display.innerHTML = 0;
      workingOperation = input;
    }
  } else if (input === "equals") {
    let result = calculate(trailingResult, display.innerHTML, workingOperation);
    display.innerHTML = result;
    trailingResult = parseFloat(result);
    workingOperation = "";
  } else if (input === "decimal"){
    if (display.innerHTML.indexOf(".") === -1){
      display.innerHTML += ".";
    }
  } else {
    display.innerHTML += input;
  }
}

function clearDisplay() {
  let display = document.getElementById("display");
  display.innerHTML = 0;
}

function calculate(firstNumber, secondNumber, operation) {
  let result;
  firstNumber = parseFloat(firstNumber);
  secondNumber = parseFloat(secondNumber);
  switch (operation) {
    case "add":
      result = firstNumber + secondNumber;
      break;
    case "subtract":
      result = firstNumber - secondNumber;
      break;
    case "multiply":
      result = firstNumber * secondNumber;
      break;
    case "divide":
      result = firstNumber / secondNumber;
      break;
    default:
      // code block
  }
  return result;
}



</script>


</head>
<body>
    <title>Calculator by Diemer</title>

<div class="calculator-grid">
    <div class="display" id="display"> 
        <div class="previous-operand"></div>
        <div class="current-operand"> </div>
    </div>
    <button onclick="clearDisplay()"  id="clear"  class="span-two">AC</button>
    <button onclick="updateDisplay('divide')" id="divide">/</button>
    <button onclick="updateDisplay('multiply')"id="multiply">*</button>
    <button onclick="updateDisplay(7)" id="seven">7</button>
    <button onclick="updateDisplay(8)" id="eight">8</button>
    <button onclick="updateDisplay(9)" id="nine">9</button>
    <button onclick="updateDisplay('subtract')" id="subtract">-</button>
    <button onclick="updateDisplay(4)" id="four">4</button>
    <button onclick="updateDisplay(5)" id="five">5</button>
    <button onclick="updateDisplay(6)" id="six">6</button>
    <button onclick="updateDisplay('add')" id="add">+</button>
    <button onclick="updateDisplay(1)" id="one">1</button>
    <button onclick="updateDisplay(2)" id="two">2</button>
    <button onclick="updateDisplay(3)" id="three">3</button>
    <button onclick="updateDisplay('decimal')" id="decimal">.</button>
   <!-- <button onclick="updateDisplay('-')" id="negative-value">+/-</button> -->
    <button onclick="updateDisplay(0)" id="zero">0</button>
    <button onclick="updateDisplay('equals')" class="span-two" id="equals">=</button>
    
</div>
</body>

<script src="https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous"></script>

</html>

CSS:
*, *::before, *::after {
    box-sizing: border-box;
  }
  
  body {
    margin: 0;
    background: linear-gradient(to right, #00aaff, #00ff6c);
  }
  
  .calculator-grid {
    display: grid;
    margin-top: 4rem;
    margin-bottom: 4rem;
    justify-content: center;
    grid-template-columns: repeat(4, 6rem);
    grid-template-rows: minmax(7rem, auto) repeat(5, 6rem);
  }
  
  .calculator-grid > button {
    cursor: pointer;
    font-size: 2rem;
    border: 1px solid white;
    outline: none;
    background-color: rgba(255,255,255, .75);
  }
  
  .calculator-grid > button:hover,
  .calculator-grid > button:focus {
    background-color: rgba(255,255,255, .9);
  }
  
  .span-two {
    grid-column: span 2;
  }
  
  .display {
    grid-column: 1 /  -1;
    background-color: rgb(0,0,0);
    color: white;
    font-size: 1,5rem;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-content: space-around;
    padding: .75rem;
    word-wrap: break-word;
    word-break: break-all;
  }
  

I already googled it, checked the FCC forum, tried chatGPT and made most of this calculator along with a video of Useful Programmer but he didn’t made a video on how to solve this.

2

Answers


  1. Use parseFloat() to parse the input. parseFloat will parse the input up to the first character that can’t be interpreted as a number.

    For the example input 5*-5, to extract the first operand parseFloat(5*-5) will return 5 as a number. Convert that to a string, find how long the string is, and truncate that length from the start of the input to leave an input *-5.

    Then, to get the operator, get the first character of the remaining input, which is *. Truncate the first character to be left with the input for the remaining operand.

    const inputEl = document.querySelector('input')
    const buttonEl = document.querySelector('button')
    const resultEl = document.querySelector('#result')
    
    buttonEl.addEventListener('click', () => {
      let input = inputEl.value
      
      const operand1 = parseFloat(input)
      input = input.slice(operand1.toString().length)
      
      const operator = input.charAt(0)
      input = input.slice(1)
      
      const operand2 = parseFloat(input)
      
      let result = 0
      switch (operator) {
        case '*':
          result = operand1 * operand2
          break
        case '/':
          result = operand1 / operand2
          break
        case '+':
          result = operand1 + operand2
          break
        case '-':
          result = operand1 - operand2
          break
      }
      
      resultEl.innerHTML = result
    })
    <input type="text" value="5*-3">
    
    <button>Calculate</button>
    
    <div id="result"></div>
    Login or Signup to reply.
  2. To allow the "-" button to be used for both subtraction and negative values, you can modify the updateDisplay function to handle the input differently depending on the context.

    If the "-" button is pressed when the display is empty, it should be interpreted as the start of a negative number. If it is pressed after an operator, it should also be interpreted as the start of a negative number. If it is pressed after a number, it should be interpreted as a subtraction operator.

    function updateDisplay(input) {
      let display = document.getElementById("display");
    
      if (display.innerHTML === "0" && operationOptions.indexOf(input) === -1) {
        if (input === 'decimal') {
          display.innerHTML = "0.";
        } else if (input === '-') {
          display.innerHTML = "-";
        } else {
          display.innerHTML = input;
        }
      } else if (operationOptions.indexOf(input) >= 0){
        // dealing without initial operand
        if (workingOperation === "") {
          workingOperation = input;
          trailingResult = display.innerHTML;
          display.innerHTML = 0;
        } else if (operationOptions.indexOf(display.innerHTML.slice(-1)) >= 0) {
          workingOperation = input;
        }
        // dealing with a set operand
        else {
          trailingResult = calculate(trailingResult, display.innerHTML, workingOperation);
          display.innerHTML = 0;
          workingOperation = input;
        }
      } else if (input === "equals") {
        let result = calculate(trailingResult, display.innerHTML, workingOperation);
        display.innerHTML = result;
        trailingResult = parseFloat(result);
        workingOperation = "";
      } else if (input === "decimal"){
        if (display.innerHTML.indexOf(".") === -1){
          display.innerHTML += ".";
        }
      } else if (input === '-') {
        // dealing with negative numbers
        if (display.innerHTML.slice(-1) === "-") {
          // remove existing negative sign
          display.innerHTML = display.innerHTML.slice(0, -1);
        } else if (operationOptions.indexOf(display.innerHTML.slice(-1)) >= 0) {
          // negative number after operator
          display.innerHTML += "-";
        } else if (display.innerHTML === "0") {
          // start of negative number
          display.innerHTML = "-";
        } else {
          // subtraction operator
          updateDisplay("subtract");
        }
      } else {
        display.innerHTML += input;
      }
    }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search