This code works as a calculator, but the scratch pad at codeacademy tells me that eval is evil. Is there another way to do the same thing without using eval?
var calculate = prompt("Enter problem"); alert(eval(calculate));
This code works as a calculator, but the scratch pad at codeacademy tells me that eval is evil. Is there another way to do the same thing without using eval?
var calculate = prompt("Enter problem"); alert(eval(calculate));
eval
evaluates the string input as JavaScript and coincidentally JavaScript supports calculations and understands 1+1
, which makes it suitable as a calculator.
If you don't want to use eval
, which is good, you have to parse that string yourself and, finally, do the computation yourself (not exactly yourself though). Have a look at this math processor, which does what you want.
Basically what you do is:
For example you have "1+2/3"
, this could evaluate to the following data structure:
"+" / \ "1" "/" / \ "2" "3"
You could then traverse that structure from top to bottom and do the computations. At first you've got the "+"
, which has a 1 on the left side and some expression on the right side, so you have to evaluate that expression first. So you go to the "/"
node, which has two numeric children. Knowing that, you can now compute 2/3
and replace the whole "/"
node with the result of that. Now you can go up again and compute the result of the "+
" node: 1 + 0.66
. Now you replace that node with the result and all you've got left is the result of the expression.
Some pseudo code on how this might look in your code:
calculation(operator, leftValue, rightValue): switch operator { case '+': return leftValue + rightValue case '-': return 42 } action(node): node.value = calculation(node.operator, action(node.left) action(node.right))
As you might have noticed, the tree is designed in such a way that it honors operator precedence. The /
has a lower level than the +
, which means it get's evaluated first.
However you do this in detail, that's basically the way to go.
You can use eval safely for a simple arithmetic calculator by filtering the input- if you only accept digits, decimal points and operators (+,-,*,/) you won't get in much trouble. If you want advanced Math functions, you are better off with the parser suggestions.
function calculate(){ "use strict"; var s= prompt('Enter problem'); if(/[^0-9()*+\/ .-]+/.test(s)) throw Error('bad input...'); try{ var ans= eval(s); } catch(er){ alert(er.message); } alert(ans); } calculate()
You can use the expression parser that is included in the math.js library:
Example usage:
math.eval('1.2 / (2.3 + 0.7)'); // 0.4 math.eval('5.08 cm in inch'); // 2 inch math.eval('sin(45 deg) ^ 2'); // 0.5 math.eval('9 / 3 + 2i'); // 3 + 2i math.eval('det([-1, 2; 3, 1])'); // -7
I write some functions when I had a problem like this. Maybe this can help:
data = [ {id:1,val1:"test",val2:"test2",val2:"test3"}, {id:2,val1:"test",val2:"test2",val2:"test3"}, {id:3,val1:"test",val2:"test2",val2:"test3"} ]; datakey = Object.keys(data[0]); // here's a fix for e['datakey[f]'] >> e[x] vix = function(e,f){ a = "string"; e[a] = datakey[f]; x = e.string; end = e[x]; delete e.string; return end; }; // here's a fix to define that variable vox = function(e,f,string){ a = "string"; e[a] = datakey[f]; x = e.string; end = e[x] = string; delete e.string; }; row = 2 // 3th row ==> {id:3,val1:"test",val2:"test2",val2:"test3"} column = 1 //datakey 2 ==> val1 vox(data[row],column,"new value"); alert(data[2].val1); //the value that we have changed