0

I have almost finished my first calculator, but I have a problem. How my calculator works is pretty simple, it asks for input via window.prompt and then adds, substracts, multiplies or divides according to what the user types. However, I've encountered a problem. I want to make it so if the user makes a spelling mistake in the keywords for the operator, it still counts; and make it so if it is realy badly typed, ask the user to type it again. Here's the code:

var num2 = window.prompt('Type in your second number')

num1 = parseFloat(num1)
num2 = parseFloat(num2)

var operator = window.prompt('Type in your operator (\"add\", \"substract\",  \"multiply\", \"divide")')

if (isNaN(num1)) {
    document.write('Please enter numbers (input1) ')
}
if (isNaN(num2)) {
    document.write('Please enter numbers (input2) ')
}

switch (operator) {
    case 'add':
    document.write(num1 + num2)
    break
  case 'substract':
    document.write(num1 - num2)
    break
  case 'multiply':
    document.write(num1 * num2)
    break
  case 'divide':
    document.write(num1 / num2)
    break
}```

Also, if you have any suggestions to improve my code, it would help. Im a very newbie programmer and I would consider this my first "project
  • I would you suggest you try something like this: https://stackoverflow.com/questions/29573700/finding-the-difference-between-two-string-in-javascript-with-regex – Anton Mar 22 '21 at 16:20
  • Also, you should change your title to something like: Detect typo in Javascript String. Try to be more specific. – Anton Mar 22 '21 at 16:22
  • I would suggest you to watch some courses on youtube, to learn all the necessary basics for javascript. Just type in youtube "Javascript full course" there will be many options to choose from. – MrJami Mar 22 '21 at 16:22
  • The best way I can think to do this would be a default case on your switch statement, and as others have pointed out, being more specific with your title, so people dont get mad at you. – Bagel03 Mar 22 '21 at 17:06

3 Answers3

0

Although your code will work, you also asked for any improvement suggestions.

I'd like to propose a more user-friendly approach that is very forgiving to the user input. (and won't require them to spell their operands)

This would require more complex code to handle this, but I think the end result will be more enjoyable.

I've done a naughty thing here, and used the eval() function to "cheat". If you just need to run this locally for yourself, you're good, but if you want to publish/share this calculator with others, you'll want to replace this with some code to parse out the equation and apply the math accordingly.

document.getElementById('input').addEventListener('input', function(e){
  var outputStr = '';
  var inputStr = this.value;
  //Can we parse the input string to get an eqation?
  //Initial support is +,-,*,/
  //(addition, subtraction, multiplication, division)
  try{
    outputStr = eval(inputStr);
    //          ^^^^ this is not a good idea (too wide open)
    //TODO: we want to parse out the parts of the equation (variables and operators) likely calling .split() on the input string, based on a regular expression
  } catch(ex){
    outputStr = 'Hmmm, invalid expression';
  }
  document.getElementById('output').innerHTML = outputStr;
});
<label for="input">Math expression</label>
<input type="text" id="input"/><br/>
Answer: <div id="output"></div>
scunliffe
  • 62,582
  • 25
  • 126
  • 161
0

If you just need a simple program that behaves like a calculator in plain JS try to edit your code like this

function calculator() {
  let num1;
  do {
      num1 = window.prompt('Type in your first number');
      if (num1 === null) {
        alert('Calculator terminated');
        return;
      }
      num1 = parseFloat(num1);
      if (isNaN(num1)) {
        alert('Please enter a valid number for num1');
      }
  } while(isNaN(num1));

  let num2;
  do {
      num2 = window.prompt('Type in your second number');
      if (num2 === null) {
        alert('Calculator terminated');
        return;
      }
      num2 = parseFloat(num2);
      if (isNaN(num2)) {
        alert('Please enter a valid number for num2');
      }
  } while(isNaN(num2));

  let operator;
  do {
      operator = window.prompt('Type in your operator (\"add\", \"substract\",  \"multiply\", \"divide")');
      
      if (operator === null) {
        alert('Calculator terminated');
        return;
      }
      
      switch (operator) {
          case 'add':
          alert(num1 + " + " + num2 + " = " + (num1 + num2));
          break
        case 'substract':
          alert(num1 + " - " + num2 + " = " + (num1 - num2));
          break
        case 'multiply':
          alert(num1 + " * " + num2 + " = " + (num1 * num2));
          break
        case 'divide':
          alert(num1 + " / " + num2 + " = " + (num1 / num2));
          break
        default:
          alert('Please enter a valid operator (add, substract, multiply, divide)');
          break
      }
  } while(operator !== 'add' && operator !== 'substract' && operator !== 'multiply' && operator !== 'divide')

}

calculator();
lpizzinidev
  • 12,741
  • 2
  • 10
  • 29
0

Here is where is become important to understand the value of functions. And separating human thinking from the problem. Instead think of it more like a task list.

In order to perform our task we need:

  1. A valid operator, Add, Subtract etc.
  2. 2 valid numbers.

So first off lets get the user to give us a valid operator:

const getValidOperator = () => {
  // Lets store our allowed operations in an array. 
  const allowed = ['add', 'subtract', 'multiply', 'divide'];
  
  const prompt = `Please select an operator from:\n ${allowed.join('\n')}`;
  
  // We will keep looping until we get a valid response.
  while(true) {
    const res = window.prompt(prompt);
    
    // Using the Array.some() method we can check 
    // if user entry is in allowed list.
    if(allowed.some(a => a === res.toLowerCase())){
      return res;
    }
  } 
}

// Just test code.
document.querySelector('p').innerText = getValidOperator();
<p></p>

At this point it is probably starting to seem obvious, we need to have a method for getting a valid number. So lets write that as well.

const getValidNumber = () => {  
  const prompt = 'Please enter a valid number:';
  
  // We will keep looping until we get a valid response.
  while(true) {
    const res = window.prompt(prompt);  
    if(!isNaN(res)) {
      return res;
    }  
  } 
}

// Just test code.
document.querySelector('p').innerText = getValidNumber();
<p></p>

Now, we need our calculator function. But we already know we have a valid operator. So we do not need to use a switch, instead we can call operators directly.

const calculator = {
  add: (p1, p2) => `${p1} + ${p2} = ${p1 + p2}`,
  subtract: (p1, p2) => `${p1} - ${p2} = ${p1 - p2}`,
  multiply: (p1, p2) => `${p1} * ${p2} = ${p1 * p2}`,
  divide: (p1, p2) => `${p1} / ${p2} = ${p1 / p2}`,
};

document.querySelector('p').innerText = calculator['add'](1,2);
<p></p>

Now, let's put all that together:

const getValidOperator = () => {
  // Lets store our allowed operations in an array. 
  const allowed = ['add', 'subtract', 'multiply', 'divide'];

  const prompt = `Please select an operator from:\n ${allowed.join('\n')}`;

  // We will keep looping until we get a valid response.
  while (true) {
    const res = window.prompt(prompt);

    // Using the Array.some() method we can check 
    // if user entry is in allowed list.
    if (allowed.some(a => a === res.toLowerCase())) {
      return res;
    }
  }
}



const getValidNumber = () => {
  const prompt = 'Please enter a valid number:';

  // We will keep looping until we get a valid response.
  while (true) {
    const res = window.prompt(prompt);
    if (!isNaN(res)) {
      return res;
    }
  }
}


const calculator = {
  add: (p1, p2) => `${p1} + ${p2} = ${p1 + p2}`,
  subtract: (p1, p2) => `${p1} - ${p2} = ${p1 - p2}`,
  multiply: (p1, p2) => `${p1} * ${p2} = ${p1 * p2}`,
  divide: (p1, p2) => `${p1} / ${p2} = ${p1 / p2}`,
};

document.querySelector('#doCalc').addEventListener('click', () => {
  const num1 = getValidNumber();
  const num2 = getValidNumber();
  const op = getValidOperator();

  document.querySelector('p').innerText = calculator[op](num1, num2);

});
<h1>Calculator</h1>
<p></p>
<button id="doCalc">Click to Start</button>

From here we can take the next step. Lets make it extensible, so that if we add a new operator it just works. Instead of having a fixed array of allowed operators, lets reflect over our calculator using Object.keys(). Using this technique we can add a new method to calculator and it magically becomes available.

const getValidOperator = (calculator) => {
  const allowed = Object.keys(calculator);
  const prompt = `Please select an operator from:\n ${allowed.join('\n')}`;

  // We will keep looping until we get a valid response.
  while (true) {
    const res = window.prompt(prompt);

    // Using the Array.some() method we can check 
    // if user entry is in allowed list.
    if (allowed.some(a => a === res.toLowerCase())) {
      return res;
    }
  }
}



const getValidNumber = () => {
  const prompt = 'Please enter a valid number:';

  // We will keep looping until we get a valid response.
  while (true) {
    const res = window.prompt(prompt);
    if (!isNaN(res)) {
      return res;
    }
  }
}

const calculator = {
  add: (p1, p2) => `${p1} + ${p2} = ${p1 + p2}`,
  subtract: (p1, p2) => `${p1} - ${p2} = ${p1 - p2}`,
  multiply: (p1, p2) => `${p1} * ${p2} = ${p1 * p2}`,
  divide: (p1, p2) => `${p1} / ${p2} = ${p1 / p2}`,
  mod: (p1, p2) => `${p1} % ${p2} = ${p1 % p2}`
};

document.querySelector('#doCalc').addEventListener('click', () => {
  const num1 = getValidNumber();
  const num2 = getValidNumber();
  const op = getValidOperator(calculator);
  document.querySelector('p').innerText = calculator[op](num1, num2);
});
<h1>Calculator</h1>
    <p></p>
    <button id="doCalc">Click to Start</button>
Bibberty
  • 4,670
  • 2
  • 8
  • 23