Fill in absent elements in an array - php

I have a code that generates total posts from a database per hour for the latest 10 hours. Now, the problem is that only hours with posts are displayed, but that won't work for me because i want to display the whole thing as a chart.
Example of the current array:
array("12"=>"20403",
"15"=>"17017",
"17"=>"84013");
The keys represent the hour in a 24 format. So what i need is a function that fills in the empty hours with 0 value.
Example:
$currenthour=date('H'); // i think it may be based on the latest hour.
array("11"="0",
"12"=>"20403",
"13"=>"0",
"14"=>"0",
"15"=>"17017",
"16"=>"0",
"17"=>"84013",
"18"=>"0",
"19"=>"0",
"20"=>"0");
Thanks!

foreach(range(0, 23) as $hour)
if(!isset($ary[$hour]))
$ary[$hour] = 0;
ksort($ary);
to fill in only last hours you may need something like
function last_hours($hour, $cnt) {
return $hour < $cnt - 1 ?
array_merge(range($hour, 0), range(23, 25 - $cnt + $hour)) :
range($hour, $hour - $cnt + 1);
}
and then
$now = date("G");
$new_array = array();
foreach(last_hours($now, 10) as $hour)
$new_array[$hour] = isset($ary[$hour]) ? $ary[$hour] : 0;

Use array_fill OR do it with a loop (assuming $hours is your array:
$currenthour=date('H');
for($i = $currenthour; $i < 23; $i++)
if(!isset($hours[$i]))
$hours[$i] = 0;

You can simply iterate through the array, and see if the value at the index is set. Like this:
Edit with your the last 10 hours:
$currenthour=date('H')
$beginrange = $currenthour - 10
if ($beginrange =< 0)
$beginrange = 23 + $beginrange
$endrange = $currenthour
//set up the for loop
foreach(range($beginrange, $endrange) as $i)
//check if the element is set
if(!isset($array[$i]))
// set it
$array[$i] = 0;

Related

Convert Excel table to 2d array

I have next Excel table with date in first column and some data in others (B, C).
1.
2.
And I want to transform it to table like on pic 3:
To do this you need to add up the data from each row and column within an hour (don't know how to say it right) and multiply by 2400.
For example, from first picture we have (0.0022 + 0.0078 + 0.0021 + 0.0078) * 2400 ≈ 47 — first element of the table from third picture.
I'm trying to do it with PHPExcel library:
$objPHPExcel = new PHPExcel();
$objPHPExcel = PHPExcel_IOFactory::load("data.xlsx");
$highestRow = $objPHPExcel->getActiveSheet()->getHighestRow();
$day = 1;
$hour = 1;
$data = array(array());
for ($i = 1; $i < $highestRow + 1; $i++) {
$cell1 = $objPHPExcel->getActiveSheet()->getCellByColumnAndRow(1, $i)->getValue();
$cell2 = $objPHPExcel->getActiveSheet()->getCellByColumnAndRow(2, $i)->getValue();
$data[$day][$hour] += $cell1 + $cell2;
if($i % 2 == 0) { $data[$day][$hour] *= 2400; $hour++; }
if($i % 48 == 0) $day++;
if($hour % 24 == 0) $hour = 1;
}
But instead of working code I get errors
Line 22:
$data[$day][$hour] += $cell1 + $cell2;
I think that something with my 2D array and as I can see my array keys is bad (not 1-24 for hours).
What should be the code to get my data in 2D array like $data[1..29-31][1-24] or any other? Or may be it is possible to get table from picture #3 some other way?
As your line number 22 is
$data[$day][$hour] += $cell1 + $cell2;
You are trying to increment $data[$day][$hour] which is not even defined yet. You need to define it before trying to increment it. I am not sure, it will make the sheet work like you are expecting. But this will fix the error you are getting. (Add this before line 22)
if(!isset($data[$day])) {
$data[$day] = array(); //Setting the day which will get the hours in array
}
if(!isset($data[$day][$hour])) {
$data[$day][$hour] = 0; //Setting the hours which will contain the incremented values for each hour. Setting it 0, the next code blocks will increment it.
}

Do an action after two rounds of a for loop

I've got a $identifier, $start_number and $end_number.
The start number is the number where the for loop should start
counting from
The end number is where the loop should stop counting
The identifier determinates how much is getting added to the start number
This for loops looks something like this:
$start_number = 102;
$end_number = 1051;
$identifier = 24;
for($i = $start_number; $i <= $end_number; $i += $identifier) {
//The first two times, add 1 to the identifier
//The second two times (we're at 4 now) add 5 to the identifier
//The third two times (were at 6 now) add 10 to the identifier
//The fourth two times (we're at 8 now) add 20 to the identifier
//etc...
}
I want it to add a dynamic number (which changes) to the $identifier each 2 times it loops, how do i do this?
Just keep track of where you are in your loop by using a counter. Then you can use the modulus operator to determine if it an even number iteration. You can add the appropriate value by using an array to store the values to add to $identifier with the count being the key to get your correct value.
$start_number = 102;
$end_number = 1051;
$identifier = 24;
$add = array(
2 => 1,
4 => 5,
6 => 10,
8 => 20
);
$count = 1;
for($i = $start_number; $i <= $end_number; $i += $identifier) {
if ($count % 2 === 0) {
$identifier += $add[$count];
}
$count++;
}
for($i = $identifier; $i <= $end_number; $i += $identifier) {
if($i%2 == 0){
//do your work
}
}

Finding the difference between 2 dates and iterating an image based on the difference

Ive managed to loop through a table and get the difference in days between 2 dates adjacent to each other in the table.
Multiple entries have the same date, i have it now that when that date changes, it displays an image however i want it to display the image as many times as the difference in date
$sql = mysql_query("SELECT * FROM Films_Info")
or die(mysql_error());
$last_value = null;
while ($row = mysql_fetch_assoc($sql)) {
if (!is_null($last_value)) {
$a = new DateTime($row['FilmRelease']);
echo "<p>".$row['FilmName']."</p>";
$interval = $a->diff(new DateTime($last_value));
//echo $interval->format('%d days');
$i = 0;
}
$howManydays = $interval->days;
for ( $i; $howManydays; $i++) {
echo "<img src=\"day.jpg\" />";
$howManydays = 0;
}
$last_value = $row['FilmRelease'];
}
for ( $i = 0; $i < $howManydays; $i++) The second is a conditional statement telling when the loop should stop.
The first section in the for loop where it says $i = 0 initialized the variable $i to 0 and then tests the condition $i < $howManydays.
Let's say $howManydays equals 1. That means 0 < 1, so the loop will perform.
At the end of the loop, the third section is called ($i++), so $i is incremented and now equals 1. The second section is called again to test conditions $i < $howManydays which is asking if 1<1 which it's not, so the loop will exit.
So if $howManydays is greater than 0, the loop should happen the integer amount that is in $howManydays.
You will want to remove $howManydays = 0; within the for loop, if you don't want it to only fire once.
The for loop
for ( $i = 0; $i < $howManydays; $i++){
// ...
}
is somewhat equivalent to the while loop:
$i = 0;
while ( $i < $howManydays ){
// ...
$i++;
}
http://php.net/manual/en/control-structures.for.php for more information
In your code above, you should also check if interval was set. You should probably just do an if rather than a while, if only need one interval.
you could just do a simple division on the interval and print out the image that many times
$last_value_u = $last_value->format('U');
$a_u = $a->format('U');
$interval = $a_u - $last_value_u;
$image_count = intval($interval/86400);
for($i=0;$i<$image_count;$i++)
echo "<p><img src=\"day.jpg\" /></p>";
Update
An alternative option would be to loop through the interval:
for($i=$last_value_u;$i<$a_u;)
{
if(intval(($a_u - $i)/86400) == X)
{
// run special code for specific day
}
else
{
// run code for every other day
}
$i+=86400;
}

Dynamic X-axis graph that will change according to the count of rows

Let's say I have a mysql table with an id, some measurements and a DATE column.
Example: id, measurements, date_entered
This table stores some measurements of a patient so as to keep a record for him.
I want to make a graph which according to the count of rows that exist in the database will change dynamically the X-axis.
For example, if there are only 7 rows in the table I need to represent 7 days to the graph with the measurement for every day. If there are more than 14 days, I want it to change to respresent 2 weeks on X-axis and the average measurements(average for 1 week and average for the other too) on Y-axis and so on from weeks to months.
Can anyone help me on this? I cannot think of something that will do in my case..
I use JPGraph to make the line graph but i don't have a problem there. My problem is on how to handle the results.
I hope you will understand what I need! Thanks.
Something like this?
// Get the results from the database
$query = "SELECT `data_col` FROM `table` WHERE `condition_col` = 'some value'";
$result = mysql_query($query);
// Get all results into array and count them
$results = array();
for ($i = 0; $row = mysql_fetch_assoc($result); $i++) {
$results[] = $row;
}
// Re-format the data depending on number of results
$data = array();
if ($i < 14) { // Less than 14 days, show per day
foreach ($results as $row) {
$data[] = $row['data_col'];
}
} else if ($i < 56) { // Less than 8 weeks, show per-week
$thisweek = array();
for ($j = 0; isset($results[$j]); $j++) { // Loop the results
$thisweek[] = $results[$j]['data_col']; // Add result to this week total
if ($j % 7 == 0 && $j > 0) { // Every 7 days...
$data[] = array_sum($thisweek) / 7; // ...calculate the week average...
$thisweek = array(); // ...and reset the total
}
}
// If there is an incomplete week, add it to the data
$data[] = array_sum($thisweek) / count($thisweek);
} else { // 8 weeks or more, show per-month
$thismonth = array();
for ($j = 0; isset($results[$j]); $j++) { // Loop the results
$thismonth[] = $results[$j]['data_col']; // Add result to this month total
if ($j % 28 == 0 && $j > 0) { // Every 28 days...
$data[] = array_sum($thismonth) / 28; // ...calculate the month average...
$thismonth = array(); // ...and reset the total
}
}
// If there is an incomplete month, add it to the data
$data[] = array_sum($thismonth) / count($thismonth);
}
// $data now contains an array from which you should be able to draw your
// graph, where array keys are (sort of) x values and array values are y
// values.
Obviously, this solution assumes a 28-day month - it does not use the calendar, simply the number of days. You could do something horrible involving working out the stats based on some values returned by date() or similar, but this would likely drastically increase the calculation overhead and slow the process down.
Hopefully this will give you a place to start.

php range query

Basic question here. I am using php(smarty) range to populate an array for days in the month.
$smarty->assign('date', range(1,31 ));
The form sends OK, but because counts start at 0, when I pick 20 from dropdown 19 gets sent in the form.
How do I set it so it starts at 1?
The range() function does not allow you to specify the keys for the array. The simplest option would be to create your own array:
$range = array();
for ($i = 1; $i <= 31; $i++) {
$range[$i] = $i;
}
$smarty->assign('date', $range);
$days = array_combine(range(1,31),range(1,31));
Or, possibly more efficient, although it's a micro-optimalisation:
$range = range(1,31);
$days = array_combine($range,$range);

Categories