Store plus and minus in a variable PHP - php

How can I solve this problem:
if ($variable == 1) {
$math = "-";
} else {
$math = "+";
}
$numberOne = 10;
$numberTwo = 10;
$result = $numberOne $math $numberTwo;
This doesn´t work, is there any way to solve this?

This will work for your example. A subtraction is the same as adding a negative. This will be far safer than the alternative of using eval.
if ($variable == 1) {
$modifier = -1;
} else {
$modifier = 1;
}
$numberOne = 10;
$numberTwo = 10;
$result = $numberOne + ($numberTwo * $modifier);

I suppose you could use eval() -- but that would be quite a bad idea (it would not be good for performances, it's not "clean", ...)
In this kind of situation, I would generally go with a switch on the operator, and one case per possible operator.
Here, it would mean using something like this :
switch ($math) {
case '+':
$result = $numberOne + $numberTwo;
break;
case '-':
$result = $numberOne - $numberTwo;
break;
}
Which can easily be extends to other operators.
(In your specific situation, if you only have + and -, though, some calculation based on a multiplication by +1 or -1 would be faster to write)

if ($variable == 1) {
$math = -1; // subtraction
} else {
$math = 1; // addition
}
$numberOne = 10;
$numberTwo = 10;
$result = $numberOne + ($math * $numberTwo);

No love for the ternary operator?
To minify Gazler's answer a bit further:
$modifier = ($variable == 1) : -1 ? 1;
$numberOne = 10;
$numberTwo = 10;
$result = $numberOne + ($numberTwo*$modifier);

If you plan to use more complex mathematics, you can use the eval() function.

Related

How do I query incomplete input

I want to transform query string like pending, shipped or cancel to number status.
$q = strtolower($keyword);
if($q == 'pen' or $q == 'pend' or $q == 'pending' ) {
$d = 1;
} elseif($q == 'shi' or $q == 'ship' or $q == 'shipped') {
$d = 2;
} elseif($q == 'can' or $q == 'cancel' ) {
$d = 3;
} else {
$d = 4;
}
$query->whereStatus($d);
Current query working fine but too much or. It's possible to do in shorten way?
str_is(query, stringToSearch) will probably be enough:
if (str_is('pen*', $q)) {
$d = 1;
}
Else you could parse them from arrays:
$pendingArray = ['pen', 'pend', 'pending'];
if (in_array($q, $pendingArray)) {
$d = 1;
}
If these are all the conditions you need, you could always use a switch.
$q = strtolower($keyword);
$d = 4;
switch($q) {
case 'pen':
case 'pend':
case 'pending':
case 'pen':
$d = 1;
break;
case 'shi':
case 'ship':
case 'shipped':
$d = 2;
break;
case 'can':
case 'cancel':
$d = 3;
break;
}
$query->whereStatus($d);
If this needs to be called on a model, it could be saved to a Laravel scope function like so:
on Laravel model
public function scopeSearchStatus($query, $keyword) {
/** All the code above **/
}
Then it can be called cleanly anywhere you'd like:
SomeModel::searchStatus($keyword);
You could also try this:
<?php
$q = strtolower($keyword);
$d = (preg_match('/\b(pen|pend|pending)\b/', $q)) ? 1 : 4;
$d = (preg_match('/\b(shi|ship|shipped)\b/', $q)) ? 2 : 4;
$d = (preg_match('/\b(can|cancel|)\b/', $q)) ? 3 : 4;
$query->whereStatus($d);

PHP variable is not shown as an integer

if($koltukk%4 == 2){
if($koltukk > 1000){
$koltukH = "B";
(int)$koltukR = ($koltukk / 4) + 1;//Doesnt work (int)
}
else{
$koltukH = "E";
(int)$koltukR = ($koltukk / 4) + 1;//Doesnt work (int)
}
}
$koltukR = ($koltukk / 4) + 1;
I want to get the $koltukR variable as an integer but i couldn't do it (int) did not work
You need to use the (int) casting on the other side of the assignment operator:
$koltukR = (int)(($koltukk / 4) + 1);
Or, use intval() like this:
$kolturR = intval(($koltukk / 4) + 1);
$koltukR = intval(($koltukk / 4) + 1);
You should use better variable names, move the math out of the if/else since both are the same, and you shouldn't even need to cast this as an int manually.
PHP has an intval() method that turns a variable into an integer. Pass in your variable as a parameter.
intval()
<?php
if($koltukk%4 == 2)
{
if($koltukk > 1000)
{
$koltukH = "B";
$koltukR = (int)(($koltukk / 4) + 1);
} else{
$koltukH = "E";
$koltukR = (int)(($koltukk / 4) + 1);
}
}
echo $koltukR;
?>
One important note here: intval() is NOT round(). intval() is similar to floor().
I think what you really want is round():
Here's the real answer: K.I.S.S.
if($k%4 == 2){
if($k > 1000){
$H = "B"
}
else{
$H = "E";
}
}
$R = round($k / 4) + 1;
Stealing an example from http://us2.php.net/intval to illustrate:
echo number_format(8.20*100, 20), "<br />";
echo intval(8.20*100), "<br />";
echo floor(8.20*100), "<br />";
echo round(8.20*100), "<br />";
819.99999999999988631316
819
819
820

PHP "Maximum execution time"

I'm trying to program my own Sine function implementation for fun but I keep getting :
Fatal error: Maximum execution time of 30 seconds exceeded
I have a small HTML form where you can enter the "x" value of Sin(x) your looking for and the number of "iterations" you want to calculate (precision of your value), the rest is PhP.
The maths are based of the "Series definition" of Sine on Wikipedia :
--> http://en.wikipedia.org/wiki/Sine#Series_definition
Here's my code :
<?php
function factorial($int) {
if($int<2)return 1;
for($f=2;$int-1>1;$f*=$int--);
return $f;
};
if(isset($_POST["x"]) && isset($_POST["iterations"])) {
$x = $_POST["x"];
$iterations = $_POST["iterations"];
}
else {
$error = "You forgot to enter the 'x' or the number of iterations you want.";
global $error;
}
if(isset($x) && is_numeric($x) && isset($iterations) && is_numeric($iterations)) {
$x = floatval($x);
$iterations = floatval($iterations);
for($i = 0; $i <= ($iterations-1); $i++) {
if($i%2 == 0) {
$operator = 1;
global $operator;
}
else {
$operator = -1;
global $operator;
}
}
for($k = 1; $k <= (($iterations-(1/2))*2); $k+2) {
$k = $k;
global $k;
}
function sinus($x, $iterations) {
if($x == 0 OR ($x%180) == 0) {
return 0;
}
else {
while($iterations != 0) {
$result = $result+(((pow($x, $k))/(factorial($k)))*$operator);
$iterations = $iterations-1;
return $result;
}
}
}
$result = sinus($x, $iterations);
global $result;
}
else if(!isset($x) OR !isset($iterations)) {
$error = "You forgot to enter the 'x' or the number of iterations you want.";
global $error;
}
else if(isset($x) && !is_numeric($x)&& isset($iterations) && is_numeric($iterations)) {
$error = "Not a valid number.";
global $error;
}
?>
My mistake probably comes from an infinite loop at this line :
$result = $result+(((pow($x, $k))/(factorial($k)))*$operator);
but I don't know how to solve the problem.
What I'm tring to do at this line is to calculate :
((pow($x, $k)) / (factorial($k)) + (((pow($x, $k))/(factorial($k)) * ($operator)
iterating :
+ (((pow($x, $k))/(factorial($k)) * $operator)
an "$iterations" amount of times with "$i"'s and "$k"'s values changing accordingly.
I'm really stuck here ! A bit of help would be needed. Thank you in advance !
Btw : The factorial function is not mine. I found it in a PhP.net comment and apparently it's the optimal factorial function.
Why are you computing the 'operator' and power 'k' out side the sinus function.
sin expansion looks like = x - x^2/2! + x^3/3! ....
something like this.
Also remember iteration is integer so apply intval on it and not floatval.
Also study in net how to use global. Anyway you do not need global because your 'operator' and power 'k' computation will be within sinus function.
Best of luck.
That factorial function is hardly optimal—for speed, though it is not bad. At least it does not recurse. It is simple and correct though. The major aspect of the timeout is that you are calling it a lot. One technique for improving its performance is to remember, in a local array, the values for factorial previously computed. Or just compute them all once.
There are many bits of your code which could endure improvement:
This statement:
while($iterations != 0)
What if $iterations is entered as 0.1? Or negative. That would cause an infinite loop. You can make the program more resistant to bad input with
while ($iterations > 0)
The formula for computing a sine uses the odd numbers: 1, 3, 5, 7; not every integer
There are easier ways to compute the alternating sign.
Excess complication of arithmetic expressions.
return $result is within the loop, terminating it early.
Here is a tested, working program which has adjustments for all these issues:
<?php
// precompute the factorial values
global $factorials;
$factorials = array();
foreach (range (0, 170) as $j)
if ($j < 2)
$factorials [$j] = 1;
else $factorials [$j] = $factorials [$j-1] * $j;
function sinus($x, $iterations)
{
global $factorials;
$sign = 1;
for ($j = 1, $result = 0; $j < $iterations * 2; $j += 2)
{
$result += pow($x, $j) / $factorials[$j] * $sign;
$sign = - $sign;
}
return $result;
}
// test program to prove functionality
$pi = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620;
$x_vals = array (0, $pi/4, $pi/2, $pi, $pi * 3/2, 2 * $pi);
foreach ($x_vals as $x)
{
$y = sinus ($x, 20);
echo "sinus($x) = $y\n";
}
?>
Output:
sinus(0) = 0
sinus(0.78539816339745) = 0.70710678118655
sinus(1.5707963267949) = 1
sinus(3.1415926535898) = 3.4586691443274E-16
sinus(4.7123889803847) = -1
sinus(6.2831853071796) = 8.9457384260403E-15
By the way, this executes very quickly: 32 milliseconds for this output.

Operators (operands?) as Parameters

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";
}

Round My number?

Round My number?
I have an number
$n = -5665.36
$round_set = can be : 1,10,10,100,1000
use the $round_set condition to get the $m
if $round_set = 1
$m = $n
if $round_set = 10
$m = -5660
if $round_set = 100
$m = -5600
if $round_set = 1000
$m = -5000
Anybody know how to round these kind of case?
Use this
intval($m/$round_set) * $round_set
http://codepad.viper-7.com/1EHFWEJ test it here.
<?php
$n = -5665.36;
$round_set = 100;
$precision = -log10($round_set);
$m = ($round_set == 1 ? $n : round($n, $precision) + $round_set);
echo $m;
?>
Wouldn't something like this work?
function rounded_nb($number, $round_set) {
return floor($number/$round_set)*$round_set;
}
For any non 0 $round_set ?
You don't need the switch, do
if($round_set > 0) {
$rounded = $round_set * floor($n / $round_set);
} else {
$rounded = $n;
}
This should pretty much do.
$rs1 = max(1, $round_set);
$m = $rs1 * floor($n / $rs1);
However a 1,10,100,... valued $round_set might make more sense.
Why not take advantage of PHP's round
$m = round($n, ($round_set == 0 ? 0 : -1 * log10($round_set)) );
Edit: Corrected edge-case of log10(0).
Edit 2: Corrected the precision.

Categories