see my code below
$rand1 = rand(0,9);
$rand2 = rand(0,9);
$operator = array('*','/','+','-');
$randoperator = $operator[rand(0,3)];
$finaalvalue = $rand1."$randoperator".$rand2;
echo $rand1.$randoperator.$rand2.'='.$finaalvalue;
i want to take two random number and do random operation like +,-,*,/ and get their value
like 2-5=6
there is some problem while doing is what am i missing
The obvious answer is to use the eval function, but its use is highly discouraged:
Caution The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is
discouraged. If you have carefully verified that there is no other
option than to use this construct, pay special attention not to pass
any user provided data into it without properly validating it
beforehand.
The other option is to write separate blocks of code that perform the desired operation, then choose the appropriate branch, for example, by using a switch...case statement:
<?php
$rand1 = rand(0, 9);
$rand2 = rand(0, 9);
$operator = array('*', '/', '+', '-');
$randoperator = $operator[rand(0, 3)];
switch ($randoperator) {
case "+":
$finaalvalue = $rand1 + $rand2;
break;
case "-":
$finaalvalue = $rand1 - $rand2;
break;
case "*":
$finaalvalue = $rand1 * $rand2;
break;
case "/":
$finaalvalue = $rand1 / $rand2;
break;
}
echo $rand1 . $randoperator . $rand2 . '=' . $finaalvalue;
if I'm reading your question right, you're computing a string, not applying the operator. You must apply code to rand1 and rand2 to compute the final value.
The easy way is to eval $finaalvalue ($finalvaalue = eval("return $finaalvalue ;");) before echoing it.
If you need the code to run fast, or don't trust the input, use a switch or a function map:
$operatorMap = array(
'+' => function($a, $b) { return $a + $b; },
'*' => function($a, $b) { return $a * $b; },
...
);
$finaalvalue = $operatorMap[$operator]($rand1, $rand2);
PHP anonymous functions run slow compared to methods and normal functions, so avoid them in tight loops where speed matters.
Is this a homework question? You should do your own work.
This should work for you:
(Also if you do random calculation's you would have to check that there is no division by zero)
<?php
function calculate_string( $mathString ) {
$mathString = trim($mathString);
$mathString = str_replace ('[^0-9\+-\*\/\(\) ]', '', $mathString);
$compute = create_function("", "return (" . $mathString . ");" );
return 0 + $compute();
}
$rand1 = rand(0,9);
$rand2 = rand(0,9);
$operator = array('*','/','+','-');
$randoperator = $operator[rand(0,3)];
if($operator = "/" && $rand2 == 0)
echo "Division by zero!";
else {
$finaalvalue = calculate_string($rand1 . $randoperator . $rand2);
echo $rand1.$randoperator.$rand2.'='.$finaalvalue;
}
?>
Suggest you to calculate mathematics operation by switch case. Your system can't perform mathematics operation, it will generate a string. That is concatenation.
$rand1 = rand(0,9);
$rand2 = rand(0,9);
$operator = array('*','/','+','-');
$randoperator = $operator[rand(0,3)];
switch($randoperator){
case '+':
$finaalvalue = $rand1 + $rand2;
break;
case '-':
$finaalvalue = $rand1 - $rand2;
break;
case '/':
if(!$rand2) $rand2++;
$finaalvalue = $rand1 / $rand2;
break;
case '*':
$finaalvalue = $rand1 * $rand2;
break;
}
echo $rand1.$randoperator.$rand2.'='.$finaalvalue;
Related
I'm beginner with php. I am trying to apply some random arithmetic operation between two variables
$operators = array(
"+",
"-",
"*",
"/"
);
$num1 = 10;
$num2 = 5;
$result = $num1 . $operators[array_rand($operators)] . $num2;
echo $result;
it prints values like these
10+5
10-5
How can I edit my code in order to do this arithmetic operation?
While you could use eval() to do this, it relies on the variables being safe.
This is much, much safer:
function compute($num1, $operator, $num2) {
switch($operator) {
case "+": return $num1 + $num2;
case "-": return $num1 - $num2;
case "*": return $num1 * $num2;
case "/": return $num1 / $num2;
// you can define more operators here, and they don't
// have to keep to PHP syntax. For instance:
case "^": return pow($num1, $num2);
// and handle errors:
default: throw new UnexpectedValueException("Invalid operator");
}
}
Now you can call:
echo compute($num1, $operators[array_rand($operators)], $num2);
This should work for you!
You can use this function:
function calculate_string( $mathString ) {
$mathString = trim($mathString); // trim white spaces
$mathString = preg_replace ('[^0-9\+-\*\/\(\) ]', '', $mathString); // remove any non-numbers chars; exception for math operators
$compute = create_function("", "return (" . $mathString . ");" );
return 0 + $compute();
}
//As an example
echo calculate_string("10+5");
Output:
15
So in your case you can do this:
$operators = array(
"+",
"-",
"*",
"/"
);
$num1 = 10;
$num2 = 5;
echo calculate_string($num1 . $operators[array_rand($operators)] . $num2);
Please check my code:
<?php
$operarors = array( '+', '-', '*' );
$randOperator = array($operarors[rand(0,2)], $operarors[rand(0,2)]);
$num1 = rand(0,10);
$num2 = rand(0,10);
$num3 = rand(0,10);
$result = $num1.$randOperator[0].$num2.$randOperator[1].$num3;
echo "The math: $num1 $randOperator[0] $num2 $randOperator[1] $num3 = $result";
?>
In the code above, I am not getting my total number of result.
Suppose I am getting 3+4*5, the output should be 23, but it is showing the string 3+4*5.
Help me please.
You can't just concatenate the operators like that. I suggest doing something like this:
<?php
function operate($op1, $operator, $op2) {
switch ($operator) {
case "+":
return $op1 + $op2;
case "-":
return $op1 - $op2;
case "*":
return $op1 * $op2;
}
}
$operators = array( '+', '-', '*' );
// performs calculations with correct order of operations
function calculate($str) {
global $operators;
// we go through each one in order of precedence
foreach ($operators as $operator) {
$operands = explode($operator, $str, 2);
// if there's only one element in the array, then there wasn't that operator in the string
if (count($operands) > 1) {
return operate(calculate($operands[0]), $operator, calculate($operands[1]));
}
}
// there weren't any operators in the string, assume it's a number and return it so it can be operated on
return $str;
}
$randOperator = array($operators[rand(0,2)], $operators[rand(0,2)]);
$num1 = rand(0,10);
$num2 = rand(0,10);
$num3 = rand(0,10);
$str = "$num1 $randOperator[0] $num2 $randOperator[1] $num3";
echo "$str = ", calculate($str), PHP_EOL;
As #AndreaFaulds said, or use callbacks: (though using array_reduce and all this array pointer magic is not necessary).
<?php
$ops = [
'+' => function ($op1, $op2) { return $op1 + $op2; },
'*' => function ($op1, $op2) { return $op1 * $op2; },
'-' => function ($op1, $op2) { return $op1 - $op2; }
];
$nums = [rand(0, 10), rand(0, 10), rand(0, 10)];
$operators = [array_rand($ops), array_rand($ops)];
$initial = array_shift($nums);
$result = array_reduce($nums, function ($accumulate, $num) use (&$operators, $ops) {
return $ops[each($operators)[1]]($accumulate, $num);
}, $initial);
Note, [] short array syntax has a version requirement of PHP 5.4+.
You should use the + operator instead of the . operator. The . just pastes it together as if the values were strings.
This question already has answers here:
Execute PHP code in a string [duplicate]
(3 answers)
Closed 8 years ago.
Say I had this code below:
$operator = "+";
$num1 = 10;
$num2 = 32;
echo "the sum of " . $num1 . " and " . $num2 . " is " . ($num1.$operator.$num2);
As you can see, I'm trying to use a variable to define the operator by concatenating it. However, when running this code, the operator is displayed as plain text instead of being used to answer the question.
Obviously, I get an output like this: "the sum of 10 and 32 is 10+32"
Surely I'm doing something wrong?
Avoid eval as much as possible. But here is the answer to do it with eval:
<?php
$operator = '+';
$num1 = 10;
$num2 = 32;
eval(sprintf('echo %d %s %d;', $num1, $operator, $num2));
Here a little cleaner code
$operator = '+';
$num1 = 10;
$num2 = 32;
switch ($operator) {
case '+':
$result = $num1 + $num2;
break;
case '-':
$result = $num1 - $num2;
break;
case '*':
$result = $num1 * $num2;
break;
case '/':
$result = $num1 / $num2;
break;
default:
echo "Invalid operator";
break;
}
echo 'Result: ' . $result;
I am trying to avoid duplicating my code by checking the variable if it is a certain operator.
Basically..
$op = $_POST['operator'];
$x = 5;
$y = 2;
$result = $x /* $op instead of '+'/'-'/'*'/'/'/'%' */ $y;
Is this possible or will I have to send the operator as a String and duplicate the code per operator type?
It's a lot safer to do something like this:
$x = 5;
$y = 2;
switch($_POST['operator']){
case '+':
$result = $x + $y;
break;
case '-':
$result = $x - $y;
break;
case '*':
$result = $x*$y;
break;
case '/':
$result = $x/$y;
break;
case '%':
$result = $x % $y;
break;
default:
$result = 'Operator not supported';
}
Something along those lines.
Ahem. You can eval.
$result = eval("$x $op $y");
But this is DANGEROUS and you should sanitize your variables with great care. There is a saying that goes something like "If your problem requires use of eval, then the problem is wrong." Something like that. It's almost certainly preferable to do something like this:
function apply_op($x, $y, $op) {
switch ($op) {
case '+': return $x + $y;
...
}
}
you can make this:
$operators = array("+", "-","*","%","/");
$op = $_POST["operator"];
if(in_array($op, $operators)) {
echo eval("$x $op $y");
} else {
echo "Operator not supported";
}
I wrote this:
$num1 = mt_rand(1,5);
$num2 = mt_rand(1,5);
$operators = array(
"+",
"-",
"*",
"/"
);
$result = $num1 . $operators[array_rand($operators)] . $num2;
(My best guess is) This doesn't work as I expected because in the array the operator is a string which makes everything a string:
var_dump($result);
Gives:
string(3) "4+3"
So my question would be how would you recommend approaching this* without changing the logic it too much?
Thanks in advance!!
*Making random operation among random numbers, and if possible, the operators should be stored in an array.
I have the feeling my title is not correctly describing the situation but I could not come up with a better idea, I'm open to suggestions :)
Of course, you could use eval to do this, but I certainly won't settle for such a solution.
I'd suggest defining a bunch of functions that take in two params and return a result, then use call_user_func_array on the result of array_rand.
function add($x, $y) { return $x + $y; }
function subtract($x, $y) { return $x - $y; }
function multiply($x, $y) { return $x * $y; }
function divide($x, $y) { return $x / $y; }
$operators = array('add', 'subtract', 'multiply', 'divide');
//...
$result = call_user_func_array($operators[array_rand($operators)], array($x, $y));
<?php
$num1 = mt_rand(1, 5);
$num2 = mt_rand(1, 5);
$operators = array(
"+",
"-",
"*",
"/"
);
switch ($operators[array_rand($operators)]) {
case "+":
$result = $num1 + $num2;
break;
case "-":
$result = $num1 - $num2;
break;
case "*":
$result = $num1 * $num2;
break;
case "/":
$result = $num1 / $num2;
break;
}
var_dump($result);
The clean solution would be to have a code branch for each operator, e.g.
function do_something($num1, $num2, $operator) {
switch ($operator) {
case '+':
return $num1 + $num2;
case '-':
return $num1 - $num2;
case '*':
return $num1 * $num2;
case '/':
return $num1 / $num2;
default:
throw new Exception('Unknown operator: '.$operator)
}
}
If you have more operators, you should create a map of operator => function and dynamically call the functions, for example:
$ftable = array(
'+' => 'fn_add',
'-' => 'fn_sub',
'*' => 'fn_mul',
'/' => 'fn_div'
);
function fn_add($a, $b) { return $a + $b; }
function fn_sub($a, $b) { return $a - $b; }
function fn_mul($a, $b) { return $a * $b; }
function fn_div($a, $b) { return $a / $b; }
function do_something($num1, $num2, $operator) {
global $ftable;
if (array_key_exists($operator, $ftable)) {
return call_user_func($ftable[$operator], $num1, $num2);
}
else {
throw new Exception('Unknown operator: '.$operator)
}
}
And of course, the unclean (slow, potentially dangerous) solution would be to use eval().
Create a function for each operation, then store operator => function name in an array.