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.
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.
im very new to PHP and im hoping someone here could help me out. i need to write a class, an when the below page echos it, it will show the answers.
<?php
include_once('Math.php');
$Math = new _Math();
echo $Math->calculate(2,3,"+")."<br />";
echo $Math->calculate(2,3,"-")."<br />";
echo $Math->calculate(2,3,"*")."<br />";
echo $Math->calculate(9,3,"/")."<br />";
echo $Math->calculate(9,0,"/")."<br />";
echo $Math->calculate("3",3,"+")."<br />";
echo $Math->calculate(2.5,3,"+")."<br />";
echo $Math->calculate(3,3,"test")."<br />";
I thought the code below would work, but im getting nothing but a blank screen.
<?php
class _Math {
function calculate(2,3,"+"){
$x = 2 + 3;
return $x;
}
function calculate(2,3,"-"){
$x = 2 - 3;
return $x;
}
function calculate(2,3,"*"){
$x = 2 * 3;
return $x;
}
function calculate(9,3,"/"){
$x = 9 / 3;
return $x;
}
function calculate(9,0,"/"){
$x = 9 / 0;
return $x;
}
function calculate("3",3,"+"){
$x = "3"+3;
return $x;
}
function calculate(2.5,3,"+"){
$x = 2.5+3;
return $x;
}
function calculate(3,3,"test"){
$x = 3 test 3;
return $x;
}
Im hoping someone can point me in the right direction. Hopefully im not that far off. Thanks in advance.
Function arguments must be variables, not expressions, which is explained in the manual.
This is a partial implementation:
class _Math
{
function calculate($op1, $op2, $type)
{
switch ($type) {
case '+':
return $op1 + $op2;
case '-':
return $op1 - $op2;
// ...
}
}
}
Inside the function you write a switch that will return the result based on the $type argument.
You function should look like this
function calculate(num1, num2, operation){
switch(operation){
case '+':
return $num1 + $num2;
break;
case '*':
return $num1 * $num2;
break;
// continue here :)
}
}
You only need 1 function. and multiple function with the same name will throw an error in PHP.
This is not how you define functions. Im not even sure what youre trying to do.
The round brackets contain the parameters which you hand over to the function. So you call a function like that:
$Math->calculate(2,3,"+")
These last 3 things are the parameters. You have to define the function like this:
function calculate($x, $y, $operation){
//your code
}
You cannot define multiple functions with the same name, so you have to check the operation and calculate it depending on the input. For example, +
function calculate($x, $y, $operation){
if($operation === "+") {
return $x + $y;
}
}
I am making very simple program in PHP . Tryig to addition first ..
But dont know ..
Here is code
<?php
$a=12;
$b=10;
$c="+";
$res=$a."$c".$b;
echo $res;
?>
it output 12+10 as it is concecate..
$c is anything.
Any idea how to do this
$c is now a string and not a expression "+" is not equal to +.
So:
$res=$a + $b;
If you would really need your structure you would have to do something evil like using eval() or you could do:
$a=12;
$b=10;
$operator='+';
switch($operator) {
case '+':
$res=$a + $b;
break;
case '-':
$res=$a - $b;
break;
}
What do you want to do exactly?
If you have the operator as a string, you could try a switch statement:
<?php
$a=12;
$b=10;
$c="+";
switch($c) {
case '+':
$res = $a + $b;
break;
case '-':
$res = $a - $b;
break;
}
var_dump($res);
?>
Yes, also PHP has an eval(uate) function:
$res = eval($a . $c . $b);
Be sure that $a, $b and $c do not stem from form input, as eval can delete and so on.
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";
}