Making many If statments into One statement. Php - php

function rawtransform{
if ($raw>=500 && $raw<=550){
$score= 1;
}
if ($raw>=550 && $raw<=600){
$score= 2;
}
if ($raw>=600 && $raw<=650){
$score= 3;
}
if ($raw>=700 && $raw<=750){
$score= 4;
}
if ($raw>=750 && $raw<=800){
$score= 5;
}
if ($raw>=800 && $raw<=850){
$score= 6;
}
if ($raw>=850 && $raw<=900){
$score= 7;
}
if ($raw>=900 && $raw<=950){
$score= 8;
}
if ($raw>=950 && $raw<=1000){
$score= 9;
}
}
This seems very basic and not very well coded. (I am only learning php )
Can anyone offer a better way of doing this? maybe a single if statement. I think there is a way just cant get my head round it.
Thanks

How about just using math?
function rawtransform($raw) {
$score = (int)($raw/50)-9;
}
You may want to add a range check for the input, though.

You can create a list of conditions, and loop through the and apply the if.
$conditions = array(
array(500, 550, 1), // greater than value, lesser than value, assignment value
array(550, 600, 2),
array(650, 700, 3) // add the rest of the conditions
);
foreach($conditions as $condition) {
if($raw >= $condition[0] && $raw <= $condition[1]) {
$score = $condition[2];
}
}

if ($raw >= 500 && $raw<= 1000){
$score = ceil(($raw-500)/50);
}

You can use if...else constructs.
if ($raw>=500 && $raw<=550){
$score= 1;
}
elseif ($raw>=550 && $raw<=600){
$score= 2;
}
elseif ($raw>=600 && $raw<=650){
$score= 3;
}
That way, if the script encounters a size of, say, 575 it won't even bother to go through the following conditions.
In your given example, the script can be simplified by:
function rawtransform($raw) { $score = floor(($raw - 450)/50); return $score; }

Your logic seems to be that you are subtracting 450 from raw, then dividing it by 50 and rounding down to the nearest whole number. (There are problems in your implementation however, as if raw is a factor of 50, it will meet the requirements for two of the if statements and there is a condition missing for when it falls between 650 and 700.)
You could do this as follows:
floor(($raw-450)/50)

Related

php - percentage chance of winning

Currently I have this:
$chance = 5;
#Set the winning chances.
function winningChance($percentage)
{
if ($percentage < 0 || $percentage > 100)
throw new Exception('Invalid percentage');
return rand(0, 100) <= $percentage ? 'won' : 'lost';
}
if(winningChance($chance) == "lost"){
$won = false; //You lost.
}else{
$won = true; //You won.
}
This is really simple. It seems like even though the $chance is set to 5, the winning occur way more often than it should.
Can anyone suggest me how to improve this?

Wrong calculation

I got a weird problem.
I want a simple system which shows an error if there are more than 1 request in one second.
What i did:
if(!isset($_SESSION['protect']['mass_request_time']) || $_SESSION['protect']['mass_request_time'] = null) {
$_SESSION['protect']['mass_request_time'] = microtime(true);
$_SESSION['protect']['mass_request_request'] = 1;
} else {
$_SESSION['protect']['mass_request_request'] += 1;
if($_SESSION['protect']['mass_request_request'] >= 2 && microtime(true) - $_SESSION['protect']['mass_request_time'] < 1) {
die('Too many requests!');
} elseif(microtime(true) - $_SESSION['protect']['mass_request_time'] > 1) {
# Reset the counter since more than a second is over
$_SESSION['protect']['mass_request_time'] = null;
}
I have no clue what i did wrong, i guess the solution is pretty easy (maybe just a calculation error.. it's already 3 AM here).
Your first if statement isn't valid.
$time = $_SESSION['protect']['mass_request_time'];
if (!isset($time) || $time = null)
Your code just just sets the time to null. Use == instead.

Any idea for knowing if the certain percent of chance triggers

I have a game development project and I have specific character one of the skill of the character is that it has a 10% chance of doubling its attack.
Question: How can I trigger it?
I hope i understand ure question:
<?php
$random = rand(1,10);
if(($random == 1) || ($random == 2) || ($random == 3))
$value += $value;
?>
Here you have a 30% chance to hit 1, 2 or 3.. and if its hit then your value gets doubled.
Ok now for your Update u just need a 10% chance? But okay:
<?php
$random = rand(1,10);
if($random == 1)
$value += $value;
?>
function doubleHit($percentChance = 30)
{
if (mt_rand(1,100) <= $percentChance) {
return true;
}
return false;
}
var_dump(doubleHit(35)); // will return either true / false
Note that this is only pseudorandom. Also note that this is faster / better than rand().
For example this code will double the value theoretically one in three times? It's hard for me to understand you.
$value = 200;
if (rand(1,3)===1) {
$value*=2;
}
Or maybe this, for percents:
$value = 200;
$percent = 30;
$chance = rand(1, 100);
if ($chance <= $percent) {
$value *= 2;
}

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.

php, how to simplify a php script?

im not sure this is a good question to post but here is my issue. I have an if statement that is getting way too long and i was wondering if there is some other kind of syntax to shorten it out:
if (($time1 <= $one_day)&&
($time2 <= $one_day)&&
($time3 <= $one_day)&&
($time4 <= $one_day)&&
($time5 <= $one_day)&&
($time1 != NULL)&&
($time2 != NULL)&&
($time3 != NULL)&&
($time4 != NULL)&&
($time5 != NULL)){
//do sometihng
}
this is one example but i have a similar one that goes up to ..&&($time15 <= $one_day).
the statement is pretty self explanatory, $time1, $time2, etc can come back empty so i have to check if they are NULL or not
any ideas?
thanks
You can put the common stuff in a function:
function validate_time($time, $one_day) {
return $time <= $one_day && $time != NULL;
}
if (validate_time($time1, $one_day) &&
validate_time($time2, $one_day) &&
validate_time($time3, $one_day) &&
validate_time($time4, $one_day) &&
validate_time($time5, $one_day)) {
// do something
}
You may want to refactor code and eliminate the need for copying & pasting those checks. Another way to get the job done:
while (true) {
foreach (array($time1, $time2, $time3, $time4, $time5) as $time) {
if ($time > $one_day || $time == NULL) {
break 2;
}
}
// do something
break;
}
The above could be put in a function as well which would make the while-loop and break keyword redundant. Replace break 2 by return then.
Using an array for you variables would help. The you can iterate over them and check.
Put the times in an array and have a for loop to do the checking.
Instead of using 15 similar but different variables, consider using an array.
If you must (or want to) keep the original variable names and not use an array here is the good solution (for $time1 to $time5):
$ok = true;
for ($i = 1; $i <= 5; $i++)
{
$var =& ${'time'.$i};
if ( ! ($var <= $one_day && $var != NULL))
{
$ok = false;
}
}
if ($ok)
{
//do something
}
You can set all the values into an Array and compare it using an For Loop.
A functionised version which should help with your reuse. This is similar to Lekensteyns code.
$times = array(
'time',
'time',
'time',
'time',
'time',
);
function validateTime($checks, $limit)
{
foreach($checks as $check) {
if($check == null || $check > $limit) {
return false;
}
}
return true;
}
if(validateTime($times,$one_day) == true) {
//codey code.
}

Categories