Help needed improving a foreach loop - php

I have this logic written that loops out an array into <li>
and gives #1 and every 5th a class of "alpha".
$count = 0;
foreach($gallery->data as $row){
if ($count==0 || $count%4==0) {
echo '<li class="alpha"></li>'.PHP_EOL;
} else {
echo '<li></li>'.PHP_EOL;
}
$count++;
}
I need to add to this and get the code adding a class of "omega" to every 4th <li>

You do realize that as you describe it, there will be some overlap right? (example - item 30 is both a '5th' and a '6th') Brian gave you an answer for exactly what you described, but I'm not sure if its what you want. You want ALPHA, x, x, x, OMEGA, ALPHA, x, x, x, OMEGA, ALPHA.....
You seem to want Alpha on the 5*k + 1, and Omega on 5*k
conditions:
alpha - ($count + 1) % 5 == 1
omega - ($count + 1) % 5 == 0
I think grouping in the addition makes this easier to understand, since you're count starts at 0 but you seem to be thinking in terms of beginning at 1. If you don't like that, lose the addition and change the equivalences to 0 and 4, respectively - $count % 5 == 0 and $count % 5 == 4
i know this is better suited for a comment under the last answer, but I don't see how. Am i not allowed until my reputation is higher or am i just missing something?>

right now as it stands your code adds the "alpha" class to every fourth item beginning with the first, not every fifth. In other words, items 1, 5, 9, 13, etc. will have a class of "alpha" since your counter begins at 0.
I assume that you want to add the "omega" class then to items 4, 8, 12, etc. Here's what you need to do that:
$count = 0;
foreach($gallery->data as $row){
if ($count%4==0) {
echo '<li class="alpha"></li>'.PHP_EOL;
}
else if ($count%4==3) {
echo '<li class="omega"></li>'.PHP_EOL;
}
else {
echo '<li></li>'.PHP_EOL;
}
$count++;
}

Related

PHP : Conditional based on the items hierarchy in array

I have this array, I want to make conditional action based on the items hierarchy in the array. I'm going to compare between items based on their hierarchy and it will result a 2 dimensional array like this.
The comparison is : Imagine that there are 3 stair, in the highest stair is 5, the second stair is 3 and the last stair is 1.
If a number compared with the 1st lower floor then it'll be 3 and if a number compared with the 2nd lower floor then it'll be 5. Example : if 5 is compared with 3 then it'll be 3, if 5 is compared with 1 then it'll be 5. If a number compared with the 1st upper floor then it'll be 1/3 and if a number compared with the 2nd upper floor then it'll be 1/5. Example if 1 is compared with 3 then it'll be 1/3 and if 1 is compared with 5 then it'll be 1/5. And if 3 is compared with 5 then it'll be 1/3 and if 3 is compared with 1 then it'll be 3.
So far, this is my code
$weightvalue = array(5,3,1);
$numbers = count($weightvalue);
for ($row = 0; $row < $numbers; $row++) {
for ($column = 0; $column < $numbers; $column++) {
echo "$weightvalue[$row],$weightvalue[$column] ";
if ($weightvalue[$row]==$weightvalue[$column]) {echo "1";}
elseif ($weightvalue[$row]<$weightvalue[$column]) {echo "1/3";}
elseif ($weightvalue[$row]<$weightvalue[$column]) {echo "1/5";}
elseif ($weightvalue[$row]>$weightvalue[$column]) {echo "3";}
elseif ($weightvalue[$row]>$weightvalue[$column]) {echo "5";}
else {echo "false";};
echo ("\n");
}
}
So far this is the result, but there're some mistakes, I know what causes this but I don't know how to fix it. Please help, any suggestion will very much appreciated.

Insert Ad element into foreach loop every 4 instances

I am adding in feed Ads to my website. I have a foreach statement that creates a list of posts. I have created a counter that is supposed to count every four posts and insert the Ad content then repeat.
I have tried some other iterations of this but this is the one I can actually get to do something. I can find a lot of info on this exact thing pertaining to wordpress. But I am running cake php and would prefer a pure php solution.
<?php
$count = 1;
foreach($stories as $story) {
echo '<h2>'.$story->title.'</h2>';
if(!empty($story->excerpt)) {
echo $story->excerpt;
} else {
echo limit_text($story->body);
}
if ($count % 4 == 1) {
echo AD_SENSE_INFEED;
}
}
$count++;
?>
This code is what I currently have but its not working the way I would like it to. As if now it basically goes every other. So POST, AD, POST AD...etc.
Your problem isn't a coding problem, its a math problem. What you're using is called modulos or remainders basically.
So that said:
if ($count % 4 == 1) {
For it to equal 1 we have to feed in something that goes in evenly once and leaves one more.
What you want to do is:
if ($count % 4 == 0) {
Aka it means there's no remainder, 4 goes into it evenly with nothing left over.
As #RiggsFolly mentioned and I completely missed this(Give his comment a up vote) your $count variable should be incremented inside the loop as well otherwise it will only increment once after the loop ends.
You can get rid of count all together (and just use the numeric index of the array)
//just some "test" data
$stories = array_fill(0, 100, []);
foreach( $stories as $count => $story) {
echo $count." ".($count % 4)."\n";
if ($count % 4 == 3) {
echo "--------------------------------------\n";
}
}
Output:
0 0
1 1
2 2
3 3
--------------------------------------
4 0
5 1
6 2
7 3
--------------------------------------
...
Sandbox
If your not sure if the keys are in proper order, you can reset them:
foreach(array_values($stories) as $count => $story) {
Obviously an array starts at 0, so you have to offset the % result a bit ... lol ... Yes I am to lazy to increment.

Pagination of PHP echoed Content

PHP is an alien language for me. I am trying to pull some fields from WP's SQL database.. The content comes out okay but is a lot. I want to somehow put it in a HTML carousel or some slider, where data must be formatted like this:
<holder1>
<data1></data1>
<data2></data2>
<data3></data3>
</holder1>
<holder2>
<data4></data4>
<data5></data5>
<data6></data6>
</holder2>
I imagine I would have to put some for loop for i<4, do, then break into holder2.
Current script that echos the data =
while($row = mysql_fetch_array($rs)) {
echo "<div class='testimonials flexslider'><ul class='slides'><li class='testimonial flex-active-slide'><blockquote><p>" . $row['post_content'] . "</p><cite><span>" . $row['post_title'] . "</cite></span></blockquote></li></ul></div>"; }
I would like it to break after 3 <li> items each, into a seperate <div> or <article> whatever I find suitable according to the carousel I use.
You need an index variable, which echoes the beginning of the wrapper when it is divisible by 3, and the end of the wrapper when it leaves a remainder of 2 after division by 3 (and at the very end). It seems like this code would work:
$index = 0;
while($row = mysql_fetch_array($rs)) {
if ($index % 3 == 0) {
echo "<div class='testimonials flexslider'><ul class='slides'>";
}
echo "<li class='testimonial flex-active-slide'><blockquote><p>" . $row['post_content'] . "</p><cite><span>" . $row['post_title'] . "</cite></span></blockquote></li>";
if ($index % 3 == 2) {
echo "</ul></div>";
}
$index++;
}
if ($index % 3 != 2) {
echo "</ul></div>";
}
EDIT: a little bit of explanation to clarify the math. Suppose you have 10 results. Because we usually count from 0 in programming, they can be numbered 0 up to 9. This would make your structure look like this:
<holder>
<data0></data0>
<data1></data1>
<data2></data2>
</holder>
<holder>
<data3></data3>
<data4></data4>
<data5></data5>
</holder>
<holder>
<data6></data6>
<data7></data7>
<data8></data8>
</holder>
<holder>
<data9></data9>
</holder>
You see that we need a <holder> before elements 0, 3, 6 and 9 - all numbers which are divisible by 3. Mathematically, this is expressed with help of the remainder function - a number is divisible by 3 when its remainder after dividing by 3 is zero.
Likewise, we need a </holder> after elements 2, 5 and 8 - numbers which after division by 3 leave a remainder of 2.
We need to take care of the situation where the last block is not complete; that's why there's an extra block of code to take care of the last </holder>.

WordPress Loop to dynamically close Bootstrap rows

I'm pretty new to PHP but I have built some fairly simple WordPress themes in my time. I'm trying to make something unique and I'm not sure how to accomplish it (or if it's even possible).
My goal is to create a loop that will dynamically close rows when it reaches the column "12" count for bootstrap (IE: col-md-3 + col-md-3 + col-md-6 = 12). The look I'm ultimately trying to achieve and how I currently have my static file set up => https://jsfiddle.net/y2mLr3hd/7/embedded/result/. I'm only using "display: flex;" for right now to just demonstrate what I'm trying to achieve. I'd like it be just rows rather than a single row.
I'm use to the standard loop for WordPress using ULs and LIs but I have no idea on how to go about what I'm trying to do. I'd like the loop to figure a random number for the column size consisting of the column sizes "3, 4, 6, 8" and create rows with columns sizes equaling "12" like I stated before. THAT or find a way on how to make it work with the way I currently have it set up.
This is the closest thing to what I'm looking for but really isn't even that close =>https://stackoverflow.com/questions/16427962/twitter-bootstrap-spans-in-dynamic-websites#=. Here's the code from that link for quick reference:
$i=0;
foreach ($posts as $post):
if ($i%2==0) echo '<div class="row-fluid">';
echo '<div class="span6">'. $post->content .'</div>';
if ($i%2==1) echo '</div>';
$i++;
endforeach;
Any help on how I might be able to go about this would be GREATLY appreciated!
There are two parts to your question:
How to divide 12 in random parts using 3, 4, 6, and 8
Given an array of numbers that add up to 12, how to generate a row with posts?
The first one is more a mathematics question. Note that you can only combine 3s and 6s, or 4s and 8s. You cannot combine 3 and 4, and still get 12.
We'll devise a simple algorithm with this in mind:
function getRandomNumbers()
{
// We start with an empty array and add numbers until we hit 12.
$result = array();
// We choose either 3 or 4 as basic number.
$x = mt_rand(3, 4);
// Now, as long as we don't hit 12, we iterate through a loop,
// adding either the basic number, or 2 times the basic number:
while (array_sum($result) < 12) {
// Randomly decide
if (mt_rand(0, 1) > 0) {
$newElement = 2 * $x; // This is either 6 or 8
// However, always make sure not to exceed 12:
if (array_sum($result) + $newElement > 12) {
$newElement = $x;
}
} else {
$newElement = $x; // This is either 3 or 4
}
// Add the new number to the array:
$result[] = $newElement;
}
// Return the resulting array
return $result;
}
Now we need to use these arrays to create rows. We start by generating an array with random numbers with the function we wrote.
We'll simply iterate through the posts, use the numbers in the array until there's none left. We'll generate a new array with random numbers whenever we need a new one. Since that means we have added 12 width-worth of columns, that's the point where we need to start a new row as well.
// Get the initial array with random numbers
$randomArray = getRandomNumbers();
// Open the initial row.
echo '<div>';
foreach ($posts as $post):
if (count($randomArray) < 1) {
// Close the row and start a new one:
echo '</div><div>';
// Get a fresh array with random numbers:
$randomArray = getRandomNumbers();
}
$nextRandomNumber = array_pop($randomArray); // This takes the next number.
echo '<div class="col-md-' . $nextRandomNumber . '">'. $post->content .'</div>';
endforeach;
echo '</div>'; // Close the final row.

How can I count the values of these cards

I'm working on a very small blackjack game in PHP.
I'm currently writing the function to count the cards, but the aces are kicking my butt.
My cards are all in an array like this:
$card_array = array( "ca", "c10", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9",
"cj", "ck", "cq", "da", "d10", "d2", "d3", "d4", "d5", "d6", "d7", "d8",
"d9", "dj", "dk", "dq", "ha", "h2", "h3", "h4", "h5", "h6", "h7", "h8", "h9",
"hj", "hk", "hq", "sa", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9",
"s10", "sj", "sk", "sq");`
Where the first character is the suit and everything after that is the card (j for jack, etc)
Here's what I have for counting the values up so far:
function bj_calculate_values( $cards ) {
$card_values = 0;
foreach ($cards as $card) {
if (substr($card, 1) == "k" || substr($card, 1) == "q" || substr($card, 1) == "j") {
$card_values += 10;
}
else if (substr($card, 1) != "a") {
$card_values += substr($card, 1);
}
}
}
Originally, I also had the ace in there valued at 11, but obviously that would cause problems. I feel like I need to keep relooping to make sure the aces don't put us over 21, but I'm not entirely sure of the best way to go about doing that.
I'd appreciate some input, guys.
EDIT:
The best I can think of is adding this to the function
foreach ($cards as $card) {
if (substr($card, 1) == "a") {
if ($card_values + 11 <= 21) {
$card_values += 11;
}
else {
$card_values += 1;
}
}
}
Actually I think this might work. Give me a few minutes to test.
EDIT:
Nope, didn't work. 4, ace, ace, 6 came out to 22 with this.
I do not know much about BlackJack, but this is my try.
function bj_calculate_values( $cards ) {
$card_values = 0;
$ace = 0;
foreach ($cards as $card) {
$val = substr($card, 1);
if (!is_numeric($val))
{
if ('a' == $val)
{
$val = 0;
$ace ++;
}
else
$val = 10;
}
$card_values += $val;
}
while ($ace)
$card_values += ($card_values + 11*$ace-- <= 21) ? 11: 1;
return $card_values;
}
UPDATE
If I understand your other comment, you want 6 4 A A A to come out 13, 6 4 A A to come out 12, and 6 4 A to come out 21. So the number of remaining aces count. Modified the source accordingly.
Explanation
First of all we calculate the value of non-ace cards. These are constant, so we get it over with. And this total is the (preliminary) $card_values.
Then we may have (or not) some aces. It makes sense to have a while($aces) so that if we have no aces, we do nothing.
And now the question is, what do we do with those aces? Here is where your requisite comes in: the sum must fit into 21. This means that I can't just say "I'm at 10, I have an ace, so it fits into 21" because there might be another ace after that. So I have to calculate what would the worst case be if I were to add in all remaining aces; and that's of course the number of aces, times 11. While the worst case is still good (i.e., $card_values + 11*$ace is less than 21) I can add 11. While it is not, I have to add 1.
It is a form of "greedy" algorithm: I fit in all the 1's we can, while ensuring enough 11's are left to reach the closest approach to 21 that does not exceed.
I seem to remember (I might be wrong, heh) that there was a nasty bug in this implementation which will come out whenever NumberOfItems * LowestValue >= HighestValue (I'm not too sure about that "equals" though). But in this case, it would require NumberOfItems to be above 11/1 = 11 aces, and there are not so many aces in the deck, so we're cool. And to be sure, the possible cases are five - from "no" to "four" aces in a hand - and easily tested for all sums of other cards:
// J Q K are worth 10, so we can use 10 instead.
// And a fake card with value of 0 stands for "nothing".
// We use the suit of Klingon, with up to four identical aces :-D
for ($first = 0; $first <= 21; $first++)
{
$hand = array("k$first");
for ($aces = 1; $aces < 5; $aces++)
{
$hand[] = "ka";
$value = bj_calculate_values($hand);
// Let us ponder the possible values of $value.
if ($value <= 11)
{
// This is an error: we could have gotten closer to 21
// by upvaluing an ace. A correct implementation will
// never enter here except in the case of a LONE ACE.
if (($first != 0) || ($aces != 1))
print "ERROR: " . implode(" ", $hand) . " = $value\n";
}
// We have a value from 12 to 21.
// Could we have done better? What cards do we have?
// If no aces, of course no. All card values are then fixed.
// If at least one ace, interpreted as 11, again not:
// cannot interpret it above 11, and interpret as 1 would LESSEN the score.
// If at least one ace, interpreted as 1, were we to interpret it
// as 11, we would be summing 10. And 12 would become 22, and blow.
// So, from 12 to 21, the result MUST be correct.
// Finally, $value more than 21.
if ($value > 21)
{
// This is admissible ONLY if we could have done no better, which
// means $value is given by the fixed cards' value, $first, plus
// ALL ACES COUNTED AS ONES.
if ($value != ($first + $aces))
print "ERROR: " . implode(" ", $hand) . " = $value\n";
}
}
}
The output (version 1)
VERIFY: k0 ka = 11 Correct, we had a lone ace and gave it 11.
VERIFY: k18 ka ka ka ka = 22 Correct, we had 18 in other cards and all A's to 1's.
VERIFY: k19 ka ka ka = 22 Ditto, 19 in cards.
VERIFY: k19 ka ka ka ka = 23 Ditto, 19 in cards.
... ...
Current output (added code to only print errors):
-- nothing :-)

Categories