Using for loop instead of if statement? - php

I am trying to familarise myself with for loop as I only understand the basics.
I am trying to simplify the code below
$round1 = $max / 2;
$round2 = $round1 + ($max / 2 / 2);
$round3 = $round2 + ($max / 2 / 2 / 2);
$round4 = $round3 + ($max / 2 / 2 / 2 / 2);
$round5 ...
With this:-
$round = array($max/2);
for ($i=1;$i<$max;$i++) {
$round[] = $round[$i -1] + $max/pow(2, $i + 1);
}
And now for the next code:-
if($matchno <= $round[0]) {
$scores_round1.= '['.$score1.', '.$score2.'],';
}
if($matchno > $round[0] AND $matchno <= $round[1]) {
$scores_round2.= '['.$score1.', '.$score2.'],';
}
if($matchno > $round[1] AND $matchno <= $round[2]) {
$scores_round3.= '['.$score1.', '.$score2.'],';
}
if($matchno > $round[2] AND $matchno <= $round[3]) {
$scores_round4.= '['.$score1.', '.$score2.'],';
}
Can the above be used in a for loop to avoid using if() ?
Thanks for help

You can check for round1 and for the rest:
for ($i=1;$i<$max;$i++) {
if($matchno>$round[$i] AND $matchno <= $round[$i+1])
${'scores_round'.$i}.='['.$score1.', '.$score2.'],';
}

for($i=0;$i< count($round); $i++){
if($match < $round[$i]){
${"scores_round".$i}.= '['.$score1.', '.$score2.'],';
break;
}
}

By watching the if statements, we notice some things:
First of all, there is no *else if* statement. That means that all if statement checks must be executed.
Additionally, there is a check whether the $matchno is less than $round[0], without any check for greater than in this if statement (the first one).
Another point is that $scores_roundX starts with X=1 and not 0.
Obviously, you will have to use one if inside the loop.
So, we are going to form loop code making some small tricks:
for($i = -1; $i < count($round)-1 ; ++$i){
if(($i = -1 OR $matchno > $round[$i]) AND ($matchno <= $round[$i+1])){
${"scores_round".$i+2} .= '['.$score1.', '.$score2.'],';
}
}
We will initialize THE $i with -1, to use it for the first statement execution.
We will put as for statement the $ to be less than the count of the
array minus 1 (because we index using $i+1 in our if statement,
inside the loop).
We will perform greater than check only if the $i is not -1, and this
will happen on the second check (second if in initial code). Here, we also use
the partial evaluation feature of the language, and that means that in the OR sub-statement,
if the first part comes as true, the second one is not ecaluated.
We will make $i+2 at the $scores_round forming, because we start from
-1 on our for loop.

Related

PHP: How to loop from 100 to 0 by -2 without letting it go infinitely?

what I am trying to achieve here is to be able to loop from 0 to 100 (100, 98, 96, 94 ...) but has to stop at 0. What is doing right now is it passes 0 and -2 -4 which crashes the server. What am I doing wrong?
for ($i = 100; $i <= 100; $i--){
echo $i--;
echo "<br>";
}
Maybe a little explanation would be useful.
The middle part of the for loop $i <= 100 is what makes it infinite. That expression is checked before each iteration of the loop, and the loop will continue as long as that expression evaluates to true.
Since you set $ito 100 in the first section of the loop, and you're doing nothing except making it smaller, it will always be <= 100, forever.
The loop will work fine just the way you have it written if you change the continuation condition.
for ($i = 100; $i >= 0; $i--){
echo $i--;
echo "<br>";
}
That way it will continue until $i is reduced to less than zero, then $i >= 0 will be false, and the loop will end.
The third argument in for loop is what will be executed at the end of the loop. So:
for ($i = 100; $i >= 0; $i -= 2){
echo "$i<br>";
}
Will do the trick
As you can read here https://secure.php.net/manual/en/control-structures.for.php
At the end of each iteration, expr3 is evaluated (executed).
Alternatively:
<?php
foreach(range(100, 0, -2) as $n) {
echo $n;
}
for ($i = 100; $i >= 0; $i-=1){
echo $i--;
echo "<br>";
}
I figured it out somehow. Has been studying JavaScript for a year; Loop is still confusing to me

Step inside foreach

How to do something every 5 (for example) cycles inside foreach?
I'm add $i++ How to check it by step?
Use modulo to determine offset.
$i = 0;
foreach ($array as $a) {
$i++;
if ($i % 5 == 0) {
// your code for every 5th item
}
// your inside loop code
}
Unless you're doing something separately in each iteration, don't.
Use a for loop and increment the counter by 5 each time:
$collectionLength = count($collection);
for($i = 0; $i < $collectionLength; i+=5)
{
// Do something
}
Otherwise, you can use the modulo operator to determine if you're on one of the fifth iterations:
if(($i + 1) % 5 == 0) // assuming i starts at 0
{
// Do something special this time
}
for($i = 0; $i < $items; $i++){
//for every 5th item, assuming i starts at 0 (skip)
if($i % 5 == 0 && $i != 0){
//execute your code
}
}

Pre-incrementation vs. post-incrementation

How are they different? Here's what I'm thinking, but I'm not sure....
If you use pre-incrementation, for example in a for loop with ++j, then you are basically saying: "Make a copy of the value of j for use in the loop, then increment j, then go through the statements in the loop with the copy of j." If you are using post-incrementation in the same loop j++, then you are basically saying: "Make a copy of the value of j for use in the loop, then go through the statements in the loop with the copy of j, then increment j."
The reason I'm unsure is because I've created a for loop that multiplies the value of j by 10 and then outputs the result for j=1 through j=12, using both post- and pre-incrementation. The human readable output is exactly the same with post- and pre-incrementation. I'm thinking, 'How are the outputs exactly the same if there isn't some kind of copy operation involved?'
So, I'm guessing the difference between pre- and post-incrementation truly becomes important, in php, when I use references (which act as pointers in php) rather than names for return values? This would be because copies of references aren't made, so pre-incrementation would be: "Increment j, then go through the statements in the loop with the changed value of j, then increment j again...," whereas post-incremetation would look like: "Use the value of j for the statements in the loop, then change the value of j, then go through the loop with the new value of j..."
Pre- or post-incrementing do not magically delay things until later. It's simply inline shorthand.
// pre-increment
$var = 5;
print(++$var); // increments first, then passes value (now 6) to print()
// post-increment
$var = 5;
print($var++); // passes value (still 5) to print(), then increments
Now let's look at a loop.
for ($i = 0; $i < 9; $i++) {
print($i);
}
The last part of the loop declaration (the $i++) is simply the statement to execute after each time through the loop. It "passes" the value to nowhere, then increments it. $i isn't used anywhere at that time. Later when the next statement is executed (print($i);), the value of $i has already increased.
// add 1, then do nothing with $i
for ($i = 0; $i < 9; ++$i) {}
// do nothing with $i, then add 1
for ($i = 0; $i < 9; $i++) {}
Whichever way you do it, $i will be the same within the loop.
If it helps, you can think of them as small routines that kind of do this:
// ++$i
{
$i = $i + 1;
return $i;
}
// $i++
{
return $i;
$i = $i + 1;
}
As I reread your question, I think the confusion is more with how the loop works than how increment operators work. Keeping in mind that the increment is a straightforward, all-at-once operation, here's how third expression in the loop works.
// here's a basic loop
for ($i = 0; $i < 9; $i++) {
// do loop stuff
print($i);
}
// this is exactly what happens
for ($i = 0; $i < 9; ) {
// do loop stuff
print($i);
$i++;
}
Just because that last line can be put in the loop declaration doesn't give it any special powers. There are no references or anything used behind the scenes. The same $i variable is seen both inside and outside the loop. Every statement inside or outside the loop directly looks up the value of $i when necessary. That's it. No funny business.
When doing $x++, you are post-incrementing... This means that the incrementation will only occur after the statement has been evaluated.
So, given the following code:
$x = 10; $y = 0; $z = 5;
$y = $z * $x++;
PHP does this:
$x = 10; $y = 0; $z = 5;
$y = $z * $x++;
// Ignore Post-Increment, Evalutate
$y = $z * $x;
$y = 5 * 10;
// Now Increment x - POST-INCREMENT
$x = $x + 1;
$x = 10 + 1;
$x = 11;
// Continue evaluating statement
$y = 5 * 10;
$y = 50;
When doing ++$x, you are pre-incrementing... This means that the incrementation will occur before the statement is evaluated:
$x = 10; $y = 0; $z = 5;
$y = $z * ++$x;
// Do Pre-Increment
$x = $x + 1;
$x = 10 + 1;
$x = 11;
// Evaluate
$y = $z * $x;
$y = 5 * 11;
$y = 55;
In the case of a for loop in PHP, PHP evaluates a for loop as follows:
for($i = 0; $i < 30; $i++) {
doSomething();
}
// Is evaluated EXACTLY as such by PHP
$i = 0;
while($i < 30) {
doSomething();
$i++;
}
The first expression ($i = 0) is evaluated (executed) once unconditionally at the beginning of the loop.
In the beginning of each iteration, $i < 30 is evaluated. If it evaluates to TRUE, the loop continues and the nested statement(s) are executed. If it evaluates to FALSE, the execution of the loop ends.
At the end of each iteration, $i++ is evaluated (executed) as an independent expression.
Therefore, post-incrementing or pre-incrementing a variable as the third expression in the loop doesn't have an effect on the behavior of it. In this simple case, both expressions will behave exactly the same.
However, in a complex loop such as the following:
for($i = $j = 0; $i < 30; $i += ++$j) {
$j = getResult($j);
}
Post-incrementing or pre-incrementing $j directly affects the value of $i according to the examples above. In this case, you need to choose exactly what you want to do.
$i = 0;
echo $i++;
echo $i;
$j=0;
echo ++$j;
echo $j;
Pre increment display incremented value. But Post increment display value then increment. About code will output 01 and 11

PHP why is continue n slower than using break

Please consider the following code:
$start = microtime();
for($i = 2; $i < 100; $i++)
{
for($y = 2; $y <= sqrt($i); $y++)
{
if($i%$y != 0)
{
continue;
}
else
{
continue 2;
}
}
echo $i.',';
}
echo "\nFinished in " . (microtime() - $start);
Given that the above code effectively uses continue 2 to break the inner loop and skip any code post the inner loop, why does the following code on average execute faster when it appears to do more:
$start = microtime();
for($i = 2; $i < 100; $i++)
{
$flag = true;
for($y = 2; $y <= sqrt($i); $y++)
{
if($i%$y != 0)
{
continue;
}
else
{
$flag = false;
break;
}
}
if($flag === true) echo $i.',';
}
echo "\nFinished in " . (microtime() - $start);
Thanks for any input.
_____ Update ____________
Thanks for the feedback but we seem to have missed the point. Regardless of if this is good programming practice I was trying to understand why the performance difference (which is tiny but consistent) is not within the bias I expected.
The passing of true to microtime seems insignificant as both samples are measured using the same method with the same overhead and the same inaccuracy.
More than one run was tested, as implied by use of the word average.
Just for illustration please consider the following small samples using microtime(true) which shows the same pattern as using microtime().
I know this is a small sample but the pattern is quite clear:
Continue
0.00037288665771484
0.00048208236694336
0.00046110153198242
0.00039386749267578
0.0003662109375
Break
0.00033903121948242
0.00035715103149414
0.00033307075500488
0.00034403800964355
0.00032901763916016
Thanks for looking, and thanks for any further feedback.
______ UPDATE Further investigation ____________
Interestingly if the echo statements are removed from the code the continue performs faster, with the echo statements in place break is faster.
Please consider the following code sample, and consider that the results are in conflict dependant on if the echo statements are removed or not:
<?php
$breakStats = array();
$continueStats = array();
ob_start();
for($i = 0; $i < 10000; $i++)
{
$breakStats[] = doBreakTest();
$continueStats[] = doContinueTest();
}
ob_clean();
echo "<br/>Continue Mean " . (array_sum($continueStats) / count($continueStats));
echo "<br/>Break Mean " . (array_sum($breakStats) / count($breakStats));
function doBreakTest()
{
$start = microtime(true);
for($i = 2; $i < 100; $i++)
{
$flag = true;
$root = sqrt($i);
for($y = 2; $y <= $root; $y++)
{
if($i%$y != 0)
{
continue;
}
else
{
$flag = false;
break;
}
}
}
if($flag === true) echo $i . '';
return microtime(true) - $start;
}
function doContinueTest()
{
$start = microtime(true);
for($i = 2; $i < 100; $i++)
{
$root = sqrt($i);
for($y = 2; $y <= $root; $y++)
{
if($i%$y != 0)
{
continue;
}
else
{
echo $i . '';
continue 2;
}
}
}
return microtime(true) - $start;
}
Echo statements present :
Continue Mean 0.00014134283065796
Break Mean 0.00012669243812561
Echo statements not present :
Continue Mean 0.00011746988296509
Break Mean 0.00013022310733795
Note that by removing the echo statement from the break and flag test we also remove the ($flag === true) check, so the load should reduce, but continue in this case still wins. W
So in a pure continue n versus break + flag scenario, it appears that continue n is the faster contstruct. But add an equal number of identical echo statements, and the continue n performance flags.
This makes sense to me logically that continue n should be faster, but I would have expected to see the same with the echo statements present.
This is clearly a difference in the generated opcodes, and the position of the echo statement (inner loop vs outer loop) does anyone know a way of seeing the opcodes generated? This I suppose is ultimatley what I need as I am trying to understand what is happening internally.
Thanks :)
Yes, first one is bit faster. It's because it just jumps out on continue 2 and prints $i.
2nd example has more job to do... assign value to $flag variable, jumps out of loop, checks $flag's value, checks $flag's type (compares too) and then prints out $i. It's bit slower (simple logic).
Anyways, has it any purpose?
Some of my results for comparing
0.0011570 < 0.0012173
0.0011540 < 0.0011754
0.0011820 < 0.0012036
0.0011570 < 0.0011693
0.0011970 < 0.0012790
Used: PHP 5.3.5 # Windows (1000 attempts; 100% first was faster)
0.0011570 < 0.0012173
0.0005000 > 0.0003333
0.0005110 > 0.0004159
0.0003900 < 0.0014029
0.0003950 > 0.0003119
0.0003120 > 0.0002370
Used: PHP 5.3.3 # Linux (1000 attempts; 32% first : 68% second was faster)
0.0006700 > 0.0004863
0.0003470 > 0.0002591
0.0005360 > 0.0004027
0.0004720 > 0.0004229
0.0005300 > 0.0004366
Used: PHP 5.2.13 # Linux (1000 attempts; 9% first : 91% second was faster)
Sorry, I don't have any more servers for testing :) Now I think it mostly depends of hardware (and maybe depends of OS too).
Generally: It proves only that Linux server is faster than one run at Windows :)
The continue 2 version is slightly faster for me. But these aren't the types of things you generally need to concern yourself with. Consider:
for($y = 2; $y <= sqrt($i); $y++)
Here you are calculating the sqrt on every iteration. Just changing that to:
$sqrt = sqrt($i);
for($y = 2; $y <= $sqrt; $y++)
will give you a much better improvement than switching between two nearly identical loop styles.
The continue 2 should be used if you find that it's easier for you to understand. The computer doesn't really care.
To address your update regarding looking at opcodes, see:
http://pecl.php.net/package/vld
php -d vld.active=1 -d vld.execute=0 -f foo.php

how to show hit counter then make it back to zero?

i want after i've been submit form it can show hit counter..
but i want after it reach "20" it can back to zero..bcoz the limit of submit is 20 times so it can't over the limit.
how do i make it works?I've been try to this code...
<?
$limit="20";
$Query_counter=mysql_query("SELECT model FROM inspec");
$Show_counter=mysql_fetch_array($Query_counter);
$show_counter = $show_counter["model"]+1;
if($show_counter > $limit[0]) {
$show_counter = 0;
}elseif ($show_counter > $limit[1]) {
$show_counter = 0;
}
$Query_update=mysql_query("UPDATE inspec SET model=$Show_counter");
$Show_counter=number_format($Show_counter);
$Show_counter=str_replace(",",".",$Show_counter);
echo "Hit:</br><strong>$show_counter</strong>";
?>
To make a counter go up to a certain value then loop back to zero, you can use the modulus operator, which in a lot of languages (including PHP and MySQL) is %
$x = 0;
$limit = 4;
for ($i = 0; $i < 10; ++$i) {
$x = ++$x % $limit;
echo $x;
}
// 1, 2, 3, 0, 1, 2, 3, 0, 1, 2
I hope that makes enough sense. I can't really figure out from the question what exactly you want... Perhaps something like this?
UPDATE `mytable` SET `mycounter` = (`mycounter` + 1) % {{the limit}}
The concept here is to test to see if the variable you're incrementing exceeds some acceptable range as a result of the next increment. Simple increment the variable, then test its value.
In your case, just add a test after you increment the counter:
$show_counter = $show_counter["model"]+1;
if($show_counter > $limit){
$show_counter = 0;
}
Be sure to define $limit to whatever number you want to cycle on.
If you want to do this for multiple thresholds you can add additional tests. Note that you could hard-code $limit to any number or any variable you want, it's just the thing you're testing against.
<?
$Query_counter=mysql_query("SELECT model FROM inspec");
$Show_counter=mysql_fetch_array($Query_counter);
$show_counter = $show_counter["model"]+1;
$x = 0;
$limit = 20;
for ($i = 0; $i < 30; ++$i) {
$x = ++$x % $limit;
echo $x;
}
$Query_update=mysql_query("UPDATE inspec SET model= (model + 1) % 20");
$Show_counter=number_format($Show_counter);
$Show_counter=str_replace(",",".",$Show_counter);
echo "Hit:</br><strong>$show_counter</strong>";
?>

Categories