Commit: 2eb10d3d2873cb00ed9068d899e5322759cd4297 Author: Levi Morrison <[email protected]> Fri, 6 Dec 2013 12:58:32 -0700 Parents: b469860e79d564c0040b5b45eae20fcf0f68a45a Branches: master
Link: http://git.php.net/?p=web/php.git;a=commitdiff;h=2eb10d3d2873cb00ed9068d899e5322759cd4297 Log: Improved comment sorting algorithm. It probably still has some room for improvements. The weights are probably not quite right, either. Changed paths: M include/shared-manual.inc Diff: diff --git a/include/shared-manual.inc b/include/shared-manual.inc index 67b3607..49dadc2 100644 --- a/include/shared-manual.inc +++ b/include/shared-manual.inc @@ -25,6 +25,118 @@ $PGI = array(); $SIDEBAR_DATA = ''; // User note display functions // ============================================================================= + +class ManualNotesSorter { + private $maxVote; + private $minVote; + private $maxAge; + private $minAge; + + private $voteFactor; + private $ratingFactor; + private $ageFactor; + + private $voteWeight = 38; + private $ratingWeight = 60; + private $ageWeight = 2; + + function sort(array &$notes) { + // First we make a pass over the data to get the min and max values + // for data normalization. + $this->findMinMaxValues($notes); + + $this->voteFactor = $this->maxVote - $this->minVote + ? (1 - .3)/ ($this->maxVote - $this->minVote) + : .5; + $this->ageFactor = $this->maxAge - $this->minAge + ? 1 / ($this->maxAge - $this->minAge) + : .5; + + $this->ageFactor *= $this->ageWeight; + + // Second we loop through to calculate sort priority using the above numbers + $this->calcSortPriority($notes); + + // Third we sort the data. + uasort($notes, array($this, 'factorSort')); + } + + + private function calcVotePriority(array $note) { + return ($note['score'] - $this->minVote) * $this->voteFactor + .3; + } + + + private function calcRatingPriority(array $note) { + if ($note['total'] <= 2) { + return 0.5; + } else { + return $note['rating']; + } + } + + + private function calcSortPriority(array &$notes) { + foreach ($notes as &$note) { + $prio = array( + 'vote' => $this->calcVotePriority($note) * $this->voteWeight, + 'rating' => $this->calcRatingPriority($note) * $this->ratingWeight, + 'age' => ($note['xwhen'] - $this->minAge) * $this->ageFactor + ); + $note['sort'] = $prio['value'] = array_sum($prio); + } + } + + + /* + * Not sure why, but using `$b['sort'] - $a['sort']` does not seem to + * work properly. + */ + private function factorSort($a, $b) { + if ($a['sort'] < $b['sort']) { + return 1; + } elseif ($a['sort'] == $b['sort']) { + return 0; + } else { + return -1; + } + } + + + private function findMinMaxValues(array &$notes) { + $count = count($notes); + if ($count <= 0) { + return; + } + $note = array_shift($notes); + $note['score'] = $net = ($note['votes']['up'] - $note['votes']['down']); + $note['total'] = $totalVotes = ($note['votes']['up'] + $note['votes']['down']); + $note['rating'] = $totalVotes > 0 + ? $note['votes']['up'] / $totalVotes + : .5; + + $this->minVote = $this->maxVote = $net; + $this->minAge = $this->maxAge = $age = $note['xwhen']; + + $first = $note; + + foreach ($notes as &$note) { + $note['score'] = $net = ($note['votes']['up'] - $note['votes']['down']); + $note['total'] = $totalVotes = ($note['votes']['up'] + $note['votes']['down']); + $note['rating'] = $totalVotes > 0 + ? $note['votes']['up'] / $totalVotes + : .5; + $age = $note['xwhen']; + $this->maxVote = max($this->maxVote, $net); + $this->minVote = min($this->minVote, $net); + $this->maxAge = max($this->maxAge, $age); + $this->minAge = min($this->minAge, $age); + } + array_unshift($notes, $first); + } +} + + // Print out all user notes for this manual page function manual_notes() { // Get needed values @@ -37,7 +149,9 @@ function manual_notes() { // Load user note for this page $notes = manual_notes_load($filename); - uasort($notes, "manual_notes_sort"); + + $sorter = new ManualNotesSorter; + $sorter->sort($notes); // Link target to add a note to the current manual page, // and it's extended form with a [+] image @@ -336,60 +450,5 @@ function relTime(DateTime $date) { return $out; } -// Sort notes by rating and group by date -function manual_notes_sort($a, $b) -{ - if ($a['votes']['up'] + $a['votes']['down'] < 1) { - $c = 1; - } else { - $c = $a['votes']['up'] + $a['votes']['down']; - } - if ($b['votes']['up'] + $b['votes']['down'] < 1) { - $d = 1; - } else { - $d = $b['votes']['up'] + $b['votes']['down']; - } - $voteA = $a['votes']['up'] / $c; - $voteB = $b['votes']['up'] / $d; - $rateA = $a['votes']['up'] - $a['votes']['down']; - $rateB = $b['votes']['up'] - $b['votes']['down']; - // Lower voted notes go to the bottom regardless of date - if ($voteA > $voteB) { - // Exception to the rule for today's notes - if ($b['xwhen'] >= mktime(0,0,0,date('n'),date('j'),date('Y')) && $voteB > -1) return 1; - // Another exception for notes with no votes compared to notes with more than 4 votes and 30% or less rating - if ($voteB === 0 && $d === 1 && $voteA <= 0.30 && $c >= 4) return 1; - return -1; - } - // Higher voted notes go to the top regardless of date - elseif ($voteA < $voteB) { - // Exception to the rule for today's notes - if ($a['xwhen'] >= mktime(0,0,0,date('n'),date('j'),date('Y')) && $voteA > -1) return -1; - // Another exception for notes with no votes compared to notes with more than 4 votes and 30% or less rating - if ($voteA === 0 && $c === 1 && $voteB <= 0.30 && $d >= 4) return -1; - return 1; - } - // Votes of equal amounts are sorted based on the overall rating and in descending order by date - else { - if ($rateA > $rateB) { - return -1; - } - elseif ($rateA < $rateB) { - return 1; - } - else { - if ($a['xwhen'] > $b['xwhen']) { - return -1; - } - elseif ($a['xwhen'] < $b['xwhen']) { - return 1; - } - else { - return 0; - } - } - } -} - /* vim: set et ts=4 sw=4: */ -- PHP Webmaster List Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
