Related
Suppose I have an array with ie. $user_all_activity in code, i must check 5 activity in 10 minute(which is done by getDifference(),which return true is condition matches).If condition matched the condition,now i must check 5 activity in 10 minute after the condition matched.And this will be repeated several times.I put some late night programming here.
//$$user_all_activity take all activity of user A
if(!$user_all_activity == NULL)
{
$size = sizeof($user_all_activity);
//$prev_array = array();
for( $i=0; $i<$size-1;$i++)
{
if($i>3)
{
$prev_array = $user_all_activity[$i-4];
$current_array = $user_all_activity[$i];
//get difference check for difference 10
if($this->getDifference($current_array,$prev_array))
{
echo "Table update at id ".$current_array['id']." </br>";
}
}
}
}
The problem for me when condition matched.I must check again the same thing.May be good to use recursive.Sorry for not explaining the problem before.Hope you get the question.Thanks
Set a variable, and then check it later.
if($user_all_activity != NULL)
{
$size = sizeof($user_all_activity);
$difference_found = false;
for( $i=0; $i<$size-1;$i++)
{
if($i>3)
{
$prev_array = $user_all_activity[$i-4];
$current_array = $user_all_activity[$i];
//get difference check for difference 10
if($this->getDifference($current_array,$prev_array))
{
echo "Table update at id ".$current_array['id']." </br>";
$difference_found = true;
}
if ($difference_found) {
// do something
}
}
}
}
The setup:
a. 2D surface
b. points (with x, y coordinates) which when connected form squares.
c. I found an algorithm that finds the intersection points of those squares so assume we have them as well.
The question is: how do I get points that contour the squares.
I've included an image for better understanding.
I was looking into http://en.wikipedia.org/wiki/Convex_hull_algorithms but it seems like they all skip those intersections (the 90' angles).
I am writing this in php but i'd love to even see a pseudo code if at all possible.
<?php
//WARNING! we assume coords as non-polar. for this to work on large-scale, you need to convert polar into decard coords.
//Can be done outside this script.
//Points sample:
$points_raw=json_decode('{"1":[[41.014357690351,-73.73715475406],[41.029170309649,-73.73715475406],[41.014357690351,-73.75644124594],[41.029178309649,-73.73721675406],[41.014365690351,-73.75650324594],[41.031554690351,-73.73806375406],[41.046091309649,-73.78489424594],[41.014688690351,-73.78819424594],[41.012691690351,-73.75993275406],[41.012691690351,-73.77921924594],[41.015809690351,-73.75893475406],[41.053689309649,-73.76006575406],[41.053689309649,-73.77935224594],[41.050793309649,-73.78376624594],[41.043862309649,-73.79638424594],[41.029049690351,-73.79638424594],[41.019350690351,-73.79608224594],[41.033268690351,-73.73637875406],[41.048081309649,-73.73637875406],[41.048081309649,-73.75566524594],[41.014365690351,-73.75644124594],[41.029170309649,-73.73721675406],[41.018165690351,-73.75650324594],[41.029178309649,-73.74662775406],[41.031554690351,-73.74662775406],[41.033268690351,-73.73806375406],[41.043862309649,-73.78489424594],[41.019350690351,-73.78819424594],[41.015809690351,-73.75993275406],[41.014688690351,-73.77921924594],[41.018165690351,-73.75893475406],[41.047266309649,-73.76006575406],[41.050793309649,-73.77935224594],[41.046091309649,-73.78376624594],[41.029049690351,-73.79608224594],[41.047266309649,-73.75566524594]]}',1);
//BEGIN HERE:
$points=$points_raw[1];
function to_round($val)
{
//here we can try conversion from polar to decard. not sure if will work
//no conversion for now, but just rounding for comparsion
return round($val*1000000000000);
}
function sort_points_array($a, $b, $which)
{
$da=to_round($a[$which]);
$db=to_round($b[$which]);
if ($da == $db) {
return 0;
}
return ($da < $db) ? -1 : 1;
}
function sort_by_0($a, $b)
{
return sort_points_array($a, $b, 0);
}
function sort_by_1($a, $b)
{
return sort_points_array($a, $b, 1);
}
//BEGIN OF UNOPTIMIZED SORT
//sort by columns from left to right (does not have to be left/right on the map)
//but we will try :) 0 -> Y, 1 -> X
//sort by X, so lower X will be on top of array.
//and each point in those columns will be also sorted from top to bottom by their Y
usort($points,"sort_by_1");
//then foreach to split array by "columns";
$column_counter=0;
$point_columns=array();
$point_columns[$column_counter][]=$points[0];
foreach($points as $n_point=>$p_coords)
{
if($n_point>0)
{
if(to_round($p_coords[1]) > to_round($point_columns[$column_counter][1][1]))
$column_counter++;
$point_columns[$column_counter][]=$p_coords;
}
}
//now sort each column
$sorted_point_columns=array();
foreach($point_columns as $pcn => $p_column)
{
usort($p_column,"sort_by_0");
$sorted_point_columns[$pcn]=$p_column;
}
//SAME TO MAKE sorted_point_rows
usort($points,"sort_by_0");
$row_counter=0;
$point_rows=array();
$point_rows[$row_counter][]=$points[0];
foreach($points as $n_point=>$p_coords)
{
if($n_point>0)
{
if(to_round($p_coords[0]) > to_round($point_rows[$row_counter][0][0]))
$row_counter++;
$point_rows[$row_counter][]=$p_coords;
}
}
$sorted_point_rows=array();
foreach($point_rows as $prn => $p_row)
{
usort($p_row,"sort_by_1");
$sorted_point_rows[$prn]=$p_row;
}
// END OF UNOPTIMIZED SORT
//output array
$final_points_poly=array();
//clearly first point will be from 1st row;
//and we will go to the RIGHT in current row to find next point
$final_points_poly[0]=$sorted_point_rows[0][0];
//and let the magic begin:
$finished=false;
$last_point_index=0;
$points_total=count($points);
$pos_x=0; //pos by columns
$pos_y=0; //pos by rows
$relative_X=0; //relative X position in current ROW;
$relative_Y=0; //relative Y position in current COLUMN;
$rule=1; // right / down = 1, left / up = -1
//detect if we go by X or Y
$going_Y=false;
$finished=false;
while(!$finished)
{
if($going_Y)
{
$relative_Y+=$rule;
$last_point_index+=1;
$cur_p=$sorted_point_columns[$pos_x][$relative_Y];
$final_points_poly[$last_point_index]=$cur_p;
$going_Y = !$going_Y;
//search for pos_y:
foreach($sorted_point_rows as $cur_y => $row)
{
if(to_round($row[0][0]) == to_round($cur_p[0]))
{
$pos_y=$cur_y;
//search for relative_X
foreach($row as $cur_rel_x => $check_point)
{
if(to_round($check_point[1]) == to_round($cur_p[1]))
{
$relative_X=$cur_rel_x;
$rule = ($relative_X % 2 == 0 ? 1 : -1);
break 2;
}
//error_check 1
if($cur_rel_x == count($row)-1)
echo "error with calculating relative_X! check your data!\n";
}
}
//error_check 2
if($cur_y == count($sorted_point_rows)-1)
echo "error with calculating pos_y! check your data!\n";
}
}
else
{
$relative_X+=$rule;
$last_point_index+=1;
$cur_p=$sorted_point_rows[$pos_y][$relative_X];
$final_points_poly[$last_point_index]=$cur_p;
$going_Y = !$going_Y;
//search for pos_x:
foreach($sorted_point_columns as $cur_x => $column)
{
if(to_round($column[0][1]) == to_round($cur_p[1]))
{
$pos_x=$cur_x;
//search for relative_Y
foreach($column as $cur_rel_y => $check_point)
{
if(to_round($check_point[0]) == to_round($cur_p[0]))
{
$relative_Y=$cur_rel_y;
$rule = ($relative_Y % 2 == 0 ? 1 : -1);
break 2;
}
//error_check 1
if($cur_rel_y == count($column)-1)
echo "error with calculating relative_Y! check your data!\n";
}
}
//error_check 2
if($cur_x == count($sorted_point_columns)-1)
echo "error with calculating pos_x! check your data!\n";
}
}
if($last_point_index == $points_total-1)
{
$finished=true;
}
}
echo "all points:\n";
print_r($final_points_poly);
/*
//generate markers for google mapping
$out = "var bbs=[];var markers=[];";
$out .= "var pinI = new google.maps.MarkerImage('http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|ADDE63');";
$out .= "var pinI2 = new google.maps.MarkerImage('http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|FF8C00');";
$out .= "var pinI3 = new google.maps.MarkerImage('http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|990099');";
$out .= "bbs.push(new google.maps.Polyline({ ";
$out .= "path: [";
foreach($final_points_poly as $m){
$out .= "new google.maps.LatLng(".join(",",$m)."),";
}
$out .= "],";
$out .= "strokeColor: 'black', strokeOpacity: 0.4, strokeWeight: 1 }));";
$f = fopen("bbs.js",'w');
fwrite($f,$out);
fclose($f);
*/
?>
Basically I want to echo only summary of my blog post on a certain page by making a function() that must limit the number of counts of words as specified there.
function sumarize($your_string){
$count++;
$maximum = 10;
foreach(explode("\n", $your_string) as $line){
$count++;
echo $line."\n";
if ($count == $maximum) break;
}
}
Lets say your table (named main) looks like that.
id | blogpost
1 sample1
2 sample2
...
At first you need to connect to db
$db=NEW MYSQLI('localhost', 'username', 'pass', 'dbname') or die ($db->error);
Then write following piece of code
function sumarize($your_string){
$count++;
$maximum = 10;
foreach(explode("\n", $your_string) as $line){
$count++;
echo $line."\n";
if ($count == $maximum) break;
}
}
$result=$db->query("SELECT `id`, `blogpost` FROM `main`");
while($row->fetch_object()){
echo sumarize($row->blogpost);
}
This is how to get work genesis φ's solution
this one takes into account numbers of character whilst ending at the last word without cutting out a character
use
select .... SUBSTR(body,1,300) .....
later you can use this function in php to cut the string at the last space or period so you wont get a half cut word in the end. The second parameter is the number of characters you want.
function shorten_string($string, $characters)
{
$shortened_string = "";
$smaller_string = substr($string, 0, $characters);
$pos_of_last_space = strrpos($smaller_string, " ");
$pos_of_last_break = strrpos($smaller_string, " ");
if (strlen($string) <= $characters) {
$shortened_string = $string;
} elseif (!$pos_of_last_space && !$pos_of_last_break) {
$shortened_string = $smaller_string;
} else {
$break_at = 0;
if ($pos_of_last_space > $pos_of_last_break) {
$break_at = $pos_of_last_space;
} else {
$break_at = $pos_of_last_break;
}
$shortened_string = substr($smaller_string, 0, $break_at);
}
}
NOTE: takes care of spaces put in html with 'nbsp'
Save the summary and body of your blog posts in different columns.
I'm trying to loop through a set of records, all of which have a "number" property. I am trying to check if there are 3 consecutive records, e.g 6, 7 and 8.
I think i'm almost there with the code below, have hit the wall though at the last stage - any help would be great!
$nums = array();
while (count($nums <= 3))
{
//run through entries (already in descending order by 'number'
foreach ($entries as $e)
{
//ignore if the number is already in the array, as duplicate numbers may exist
if (in_array($e->number, $num))
continue;
else
{
//store this number in the array
$num[] = $e->number;
}
//here i need to somehow check that the numbers stored are consecutive
}
}
function isConsecutive($array) {
return ((int)max($array)-(int)min($array) == (count($array)-1));
}
You can achieve the same result without looping, too.
If they just have to be consecutive, store a $last, and check to make sure $current == $last + 1.
If you're looking for n numbers that are consecutive, use the same, except also keep a counter of how many ones fulfilled that requirement.
$arr = Array(1,2,3,4,5,6,7,343,6543,234,23432,100,101,102,103,200,201,202,203,204);
for($i=0;$i<sizeof($arr);$i++)
{
if(isset($arr[$i+1]))
if($arr[$i]+1==$arr[$i+1])
{
if(isset($arr[$i+2]))
if($arr[$i]+2==$arr[$i+2])
{
if(isset($arr[$i+3]))
if($arr[$i]+3==$arr[$i+3])
{
echo 'I found it:',$arr[$i],'|',$arr[$i+1],'|',$arr[$i+2],'|',$arr[$i+3],'<br>';
}//if3
}//if 2
}//if 1
}
I haven't investigated it thoroughly, maybe can be improved to work faster!
This will confirm if all items of an array are consecutive either up or down.
You could update to return an array of [$up, $down] or another value instead if you need direction.
function areAllConsecutive($sequence)
{
$up = true;
$down = true;
foreach($sequence as $key => $item)
{
if($key > 0){
if(($item-1) != $prev) $up = false;
if(($item+1) != $prev) $down = false;
}
$prev = $item;
}
return $up || $down;
}
// areAllConsecutive([3,4,5,6]); // true
// areAllConsecutive([3,5,6,7]); // false
// areAllConsecutive([12,11,10,9]); // true
Here's an example that can check this requirement for a list of any size:
class MockNumber
{
public $number;
public function __construct($number)
{
$this->number = $number;
}
static public function IsListConsecutive(array $list)
{
$result = true;
foreach($list as $n)
{
if (isset($n_minus_one) && $n->number !== $n_minus_one->number + 1)
{
$result = false;
break;
}
$n_minus_one = $n;
}
return $result;
}
}
$list_consecutive = array(
new MockNumber(0)
,new MockNumber(1)
,new MockNumber(2)
,new MockNumber(3)
);
$list_not_consecutive = array(
new MockNumber(5)
,new MockNumber(1)
,new MockNumber(3)
,new MockNumber(2)
);
printf("list_consecutive %s consecutive\n", MockNumber::IsListConsecutive($list_consecutive) ? 'is' : 'is not');
// output: list_consecutive is consecutive
printf("list_not_consecutive %s consecutive\n", MockNumber::IsListConsecutive($list_not_consecutive) ? 'is' : 'is not');
// output: list_not_consecutive is not consecutive
If u don't wanna mess with any sorting, picking any of three numbers that are consecutive should give you:
- it either is adjacent to both the other numbers (diff1 = 1, diff2 = -1)
- the only number that is adjacent (diff = +-1) should comply the previous statement.
Test for the first condition. If it fails, test for the second one and under success, you've got your secuence; else the set doesn't comply.
Seems right to me. Hope it helps.
I think you need something like the following function (no need of arrays to store data)
<?php
function seqOfthree($entries) {
// entries has to be sorted descending on $e->number
$sequence = 0;
$lastNumber = 0;
foreach($entries as $e) {
if ($sequence==0 or ($e->number==$lastNumber-1)) {
$sequence--;
} else {
$sequence=1;
}
$lastNumber = $e->number;
if ($sequence ==3) {
// if you need the array of sequence you can obtain it easy
// return $records = range($lastNumber,$lastNumber+2);
return true;
}
}
// there isn't a sequence
return false;
}
function isConsecutive($array, $total_consecutive = 3, $consecutive_count = 1, $offset = 0) {
// if you run out of space, e.g. not enough array values left to full fill the required # of consecutive count
if ( $offset + ($total_consecutive - $consecutive_count ) > count($array) ) {
return false;
}
if ( $array[$offset] + 1 == $array[$offset + 1]) {
$consecutive_count+=1;
if ( $consecutive_count == $total_consecutive ) {
return true;
}
return isConsecutive($array, $total_consecutive, $consecutive_count, $offset+=1 );
} else {
return isConsecutive($array, $total_consecutive, 1, $offset+=1 );
}
}
The following function will return the index of the first of the consecutive elements, and false if none exist:
function findConsecutive(array $numbers)
{
for ($i = 0, $max = count($numbers) - 2; $i < $max; ++$i)
if ($numbers[$i] == $numbers[$i + 1] - 1 && $numbers[$i] == $numbers[$i + 2] - 2)
return $i;
return false;
}
Edit: This seemed to cause some confusion. Like strpos(), this function returns the position of the elements if any such exists. The position may be 0, which can evaluate to false. If you just need to see if they exist, then you can replace return $i; with return true;. You can also easily make it return the actual elements if you need to.
Edit 2: Fixed to actually find consecutive numbers.
I have a MySQL table holding lots of records that i want to give the user access to. I don't want to dump the entire table to the page so i need to break it up into 25 records at a time, so i need a page index. You have probably seen these on other pages, they kind of look like this at the base of the page:
< 1 2 3 4 5 6 7 8 9 >
For example, when the user clicks on the '4' link, the page refreshes and the offset is moved on (4th page x 25 records). Here is what i already have:
function CreatePageIndex($ItemsPerPage, $TotalNumberOfItems, $CurrentOffset, $URL, $URLArguments = array())
{
foreach($URLArguments as $Key => $Value)
{
if($FirstIndexDone == false)
{
$URL .= sprintf("?%s=%s", $Key, $Value);
$FirstIndexDone = true;
}
else
{
$URL .= sprintf("&%s=%s", $Key, $Value);
}
}
Print("<div id=\"ResultsNavigation\">");
Print("Page: ");
Print("<span class=\"Links\">");
$NumberOfPages = ceil($TotalNumberOfItems / $ItemsPerPage);
for($x = 0; $x < $NumberOfPages; $x++)
{
if($x == $CurrentOffset / $ItemsPerPage)
{
Print("<span class=\"Selected\">".($x + 1)." </span>");
}
else
{
if(empty($URLArguments))
{
Print("".($x + 1)." ");
}
else
{
Print("".($x + 1)." ");
}
}
}
Print("</span>");
Print(" (".$TotalNumberOfItems." results)");
Print("</div>");
}
Obviously this piece of code does not create a dynamic index, it just dumps the whole index at the bottom of the page for every page available. What i need is a dynamic solution that only shows the previous 5 pages and next 5 pages (if they exist) along with a >> or something to move ahead 5 or so pages.
Anybody seen an elegant and reusable way of implementing this as i feel i'm re-inventing the wheel? Any help is appreciated.
Zend Framework is becoming a useful collection and includes a Zend_Paginator class, which might be worth a look. Bit of a learning curve and might only be worth it if you want to invest the time in using other classes from the framework.
It's not too hard to roll your own though. Get a total count of records with a COUNT(*) query, then obtain a page of results with a LIMIT clause.
For example, if you want 20 items per page, page 1 would have LIMIT 0,20 while page 2 would be LIMIT 20,20, for example
$count=getTotalItemCount();
$pagesize=20;
$totalpages=ceil($count/$pagesize);
$currentpage=isset($_GET['pg'])?intval($_GET['pg']):1;
$currentpage=min(max($currentpage, 1),$totalpages);
$offset=($currentpage-1)*$pagesize;
$limit="LIMIT $offset,$pagesize";
It's called Pagination:
a few examples:
A nice one without SQL
A long tutorial
Another tutorial
And Another
And of course.. google
How about this jQuery-plugin?
So all the work is done on the clientside.
http://plugins.jquery.com/project/pagination
demo: http://d-scribe.de/webtools/jquery-pagination/demo/demo_options.htm
Heres an old class I dug out that I used to use in PHP. Now I handle most of it in Javascript. The object takes an array (that you are using to split the stack into pages) and return the current view. This can become tedious on giant tables so keep that in mind. I generally use it for paging through small data sets of under 1000 items. It can also optionally generate your jump menu for you.
class pagination {
function pageTotal($resultCount, $splitCount) {
if (is_numeric($resultCount) && is_numeric($splitCount)) {
if ($resultCount > $splitCount) {
$pageAverage = (integer)$resultCount / $splitCount;
$pageTotal = ceil($pageAverage);
return $pageTotal;
} else {
return 1;
}
} else {
return false;
}
}
function pageTotalFromStack($resultArray, $splitCount) {
if (is_numeric($splitCount) && is_array($resultStack)) {
if (count($resultStack) > $splitCount) {
$resultCount = count($resultStack);
$pageAverage = (integer)$resultCount / $splitCount;
$pageTotal = ceil($pageAverage);
return $pageTotal;
} else {
return 1;
}
} else {
return false;
}
}
function makePaginationURL($preURL, $pageTotal, $selected=0, $linkAttr=0, $selectedAttr=0) {
if (!empty($preURL) && $pageTotal >= 1) {
$pageSeed = 1;
$passFlag = 0;
$regLink = '<a href="{url}&p={page}"';
if (is_array($linkAttr)) $regLink .= $this->setAttributes($linkAttr); //set attributes
$regLink .= '>{page}</a>';
$selLink = '<a href="{url}&p={page}"';
if (is_array($selectedAttr)) $selLink .= $this->setAttributes($selectedAttr); //set attributes
$selLink .= '>{page}</a>';
while($pageSeed <= $pageTotal) {
if ($pageSeed == $selected) {
$newPageLink = str_replace('{url}', $preURL, $selLink);
$newPageLink = str_replace('{page}', $pageSeed, $newPageLink);
} else {
$newPageLink = str_replace('{url}', $preURL, $regLink);
$newPageLink = str_replace('{page}', $pageSeed, $newPageLink);
}
if ($passFlag == 0) {
$passFlag = 1;
$linkStack = $newPageLink;
} else {
$linkStack .= ', ' . $newPageLink;
}
$pageSeed++;
}
return $linkStack;
} else {
return false;
}
}
function splitPageArrayStack($stackArray, $chunkSize) {
if (is_array($stackArray) && is_numeric($chunkSize)) {
return $multiArray = array_chunk($stackArray, $chunkSize);
} else {
return false;
}
}
}