Jump to content


Photo

while when not set


  • Please log in to reply
4 replies to this topic

#1 AV1611

AV1611
  • Members
  • PipPipPip
  • Advanced Member
  • 997 posts

Posted 23 June 2006 - 03:54 PM

lets say you have an array like this:

[3]=>1
[4]=>2
[5]=>3
[6]=>4
([0]-[2] is missing on purpose, could be different range of numbers)

in $arr[]
and simular in $arr2[]

and you do this:
$av=0;
while ($av<=365){
$data[$av]=($arr[$av]+$arr2[$av])/2;
$av++;
}

if (obviously) gives me
Notice: Undefined offset: 0 in c:\inetpub\wwwroot\production\array2.php on line 125

because it is not in the array... how do I do it?
(Is it foreach? I can't figure out how to do the foreach)


#2 Wildbug

Wildbug
  • Members
  • PipPipPip
  • Advanced Member
  • 1,149 posts

Posted 23 June 2006 - 04:04 PM


You mean you have two arrays with the same keys and you want their average for values with the same key?

Try:
$a1 = array;
$a2 = array;
$data = array();
// ....
foreach ($a1 as $key => $value) $data[$key] = ($value + $a2[$key]) / 2;
// ... or ...
foreach (array_keys($a1) as $key) $data[$key] = ($a1[$key] + $a2[$key]) / 2;
// if you're sure the keys exist in both arrays, then that's fine.  Otherwise, you might want to use some error checking (like array_key_exists() or isset()).

Twice a day my clock works PERFECTLY!  I can't figure out what's wrong with it.

#3 kenrbnsn

kenrbnsn
  • Staff Alumni
  • Advanced Member
  • 8,235 posts
  • LocationHillsborough, NJ, USA

Posted 23 June 2006 - 04:17 PM

If you don't need to preserve the keys, you can use the [a href=\"http://www.php.net/manual/en/function.array-map.php\" target=\"_blank\"]array_map()[/a] function. If you need to preserve the keys, use foreach(). The following example shows how to use each:
<?php
$arr = array();
$arr[2] = 3;
$arr[3] = 6;
$arr[5] = 10;

$arr2 = array();
$arr2[2] = 34;
$arr2[3] = 2;
$arr2[5] = 23;

function test_array_map($a1, $a2)
{
    return(($a1 + $a2)/2);
}

$data = array_map(test_array_map,$arr,$arr2);
echo '<pre>' . print_r($data,true) . '</pre>';

$data1 = array();
foreach($arr as $key => $value)
    $data1[$key] = ($value + $arr2[$key])/2;
echo ' ----------------------<br>';
echo '<pre>' . print_r($data1,true) . '</pre>';
?>

Ken

#4 AV1611

AV1611
  • Members
  • PipPipPip
  • Advanced Member
  • 997 posts

Posted 23 June 2006 - 04:21 PM

thanks, but you just fingered my real problem:

the two arrays are NOT in sync...

I need to do two queries, both for the last 365 days,

the problem is, there will be some days where the data is in one, the other, or both...

What I need to do is this:

so the first query, and build an array,
build the second query, and build an array,

then create a third array that is the average of each date that had a result in EITHER query, then:
if both exist, take the average
if only in the first, then put that in the average array
if only in the second, then put that in the avage array

here is the full script as I have it now... I developed with random number generator, and works great, as long as there is 365 days of data... but the database only has a few days in it, so the script won't start working until next year LOL :\

$result = mysql_query("create temporary table SILK (Select
products.COMP_COUNT,runtimes.HOURS,runtimes.QTY,runtimes.
DATE_RUN,runtimes.LINE,runtimes.PN,runtimes.SIDE
From products Inner Join runtimes ON runtimes.PN = products.PART_NO)");
$result2=mysql_query("select DATE_RUN, sum((QTY/HOURS)*COMP_COUNT) as compperhour from SILK where LINE='1' group by DATE_RUN");
    while ($row=mysql_fetch_array($result2))
            {$data[]=$row[1];}
$result3=mysql_query("select DATE_RUN, sum((QTY/HOURS)*COMP_COUNT) as compperhour from SILK where LINE='2' group by DATE_RUN");
    while ($row=mysql_fetch_array($result3))
            {$data2[]=$row[1];}
// must be oldest first
$size = count($data);
$size = count($data);
$size3 = count($data);
//query1
$avgs = $sums = $nums = array();
for ($i = 0; $i < $size-29; $i++) {
     $tmp = array_slice($data, $i, 30);
     $s = array_sum($tmp);
     if($i<=28){$avgs[$i]=$tmp[$i];
         }
     $avgs[$i+29] = $s/30;
     $nums[$i+29] = join (',',$tmp);
     $sums[$i+29] = $s;
    }
$q=0;
if(isset($avgs[$q])){
        while($q<=28){
            $avgs[$q]=$avgs[29];
            $q++;
            }
        }
$f=0;
KSORT($avgs);
//query2
$avgs2 = $sums2 = $nums2 = array();
for ($i = 0; $i < $size-29; $i++) {
     $tmp2 = array_slice($data2, $i, 30);
     $s2 = array_sum($tmp2);
     if($i<=28){$avgs2[$i]=$tmp2[$i];}
     $avgs2[$i+29] = $s2/30;
     $nums2[$i+29] = join (',',$tmp2);
     $sums2[$i+29] = $s2;
    }
$q=0;
$f=0;
KSORT($avgs2);
//query2
$avgs2 = $sums2 = $nums2 = array();
for ($i = 0; $i < $size-29; $i++) {
     $tmp2 = array_slice($data2, $i, 30);
     $s2 = array_sum($tmp2);
     if($i<=28){$avgs2[$i]=$tmp2[$i];}
     $avgs2[$i+29] = $s2/30;
     $nums2[$i+29] = join (',',$tmp2);
     $sums2[$i+29] = $s2;
    }
$q=0;
if(isset($avgs[$q])){
    while($q<=28)
    {$avgs2[$q]=$avgs2[29];
    $q++;}
    }
$f=0;
KSORT($avgs2);
//query3
$av=0;
while ($av<=365){
    $data4[$av]=($data[$av]+$data2[$av])/2;
    $av++;
    }
$avgs3 = $sums3 = $nums3 = array();
for ($i = 0; $i < $size-29; $i++) {
     $tmp3 = array_slice($data4, $i, 30);
     $s3 = array_sum($tmp3);
     if($i<=28){$avgs3[$i]=$tmp3[$i];}
     $avgs3[$i+29] = $s3/30;
     $nums3[$i+29] = join (',',$tmp3);
     $sums3[$i+29] = $s3;
    }
$q=0;
while($q<=28)
{$avgs3[$q]=($avgs[$q]+$avgs2[$q])/2;
$q++;}
$f=0;
KSORT($avgs3);
// Define .PNG image
header("Content-type: image/png");
$imgWidth=913;
$imgHeight=500;
// Create image and define colors
$image=imagecreate($imgWidth, $imgHeight);
$colorWhite=imagecolorallocate($image, 255, 255, 255);
$colorGrey=imagecolorallocate($image, 220,220,220);
$colorBlue=imagecolorallocate($image, 0,0,255);
$colorBlue2=imagecolorallocate($image, 200,200,255);
$colorBlack=imagecolorallocate($image, 0,0,0);
$colorRed=imagecolorallocate($image, 255,0,0);
$colorMagenta=imagecolorallocate($image, 255,0,255);
// Create border around image
// right vert
imageline($image, 912, 500, 912, 0, $colorBlack);
// bottom horiz
imageline($image, 0,499,912,499, $colorBlack);//
// top horiz
imageline($image, 912, 0, 0, 0, $colorBlack);
// left vert
imageline($image, 0, 0, 0, 500, $colorBlack);
// some guide lines
imageline($image, 0, 101, 912, 101, $colorBlack);
imageline($image, 0, 201, 912, 201, $colorBlack);
imageline($image, 0, 301, 912, 301, $colorBlack);
imageline($image, 0, 401, 912, 401, $colorBlack);
imageline($image, 224, 0, 224, 500, $colorBlack);
imageline($image, 449, 0, 449, 500, $colorBlack);
imageline($image, 674, 0, 674, 500, $colorBlack);
// Create grid i<52 means 52 verticals
for ($i=1; $i<365;){
//H
imageline($image, $i*2.5, 0, $i*2.5, 913, $colorGrey);
//V
imageline($image, 0, $i*25, 913, $i*25, $colorGrey);
$i++;
}
// $graphValuesR = array_reverse($graphValues);
// Create line graph
// $avgs = array_reverse($avgs);
// imageline(x1,y1,x2,y2)

//query1 - 30 day rolling avg
for ($i=0; $i<365; $i++){
     if (isset($avgs[$i+1])) {
     imageline($image,
     ($i*2.5),(500-($avgs[$i])*25/1000*2 ),
     (($i+1)*2.5),(500-($avgs[$i+1])*25/1000*2 ),
     $colorBlue);
    }
}
//query2
for ($i=0; $i<365; $i++){
     if (isset($avgs2[$i+1])) {
     imageline($image,
     ($i*2.5),(500-($avgs2[$i])*25/1000*2 ),
     (($i+1)*2.5),(500-($avgs2[$i+1])*25/1000*2 ),
     $colorRed);
    }
}
//query3
for ($i=0; $i<365; $i++){
     if (isset($avgs3[$i+1])) {
     imageline($image,
     ($i*2.5),(500-($avgs3[$i])*25/1000*2 ),
     (($i+1)*2.5),(500-($avgs3[$i+1])*25/1000*2 ),
     $colorMagenta);
    }
}
// Output graph and clear image from memory
imagepng($image);
imagedestroy($image);



#5 Wildbug

Wildbug
  • Members
  • PipPipPip
  • Advanced Member
  • 1,149 posts

Posted 23 June 2006 - 05:34 PM

Oh, that's a little different.

If I'm reading your code correctly, you could do something like the following where you load up an inital array with the values from your query, keyed by the date, then run through the second dataset, averaging only if the key/value is already set:

$data_average = array();
foreach ($data as $value) $data_average[$value['DATE_RUN']] = $value['compperhour'];
foreach ($data2 as $value) {
    if (isset($data_average[$value['DATE_RUN']])) {
        $data_average[$value['DATE_RUN']] = ($data_average[$value['DATE_RUN']] + $value['compperhour']) / 2;
    } else {
        $data_average[$value['DATE_RUN']] = $value['compperhour'];
    }
}

If you need to flesh out the rest of the array where there are missing values, might I suggest using a combination of PHP's date functions. If you are doing this, say, by calender year, you might create a loop that increments date('Y-m-d',strtotime("2006-01-01") + 86400*$i) to $i < 365.

Does that scratch where it itches?


(Btw, you might be able to do that same MySQL query without the temp table...)
Twice a day my clock works PERFECTLY!  I can't figure out what's wrong with it.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users