Jump to content

Forum 'Likes' and 'Posts' and the TOP-List


horst
 Share

Recommended Posts

--------------------------------------------------------------------------------------------------------------------

  EDIT (08.01.2014): finally a sortable Table is here: http://ranking.pw.nogajski.de/

   (more info is here: http://processwire.com/talk/topic/5290-topposters-oldcode-more/)

--------------------------------------------------------------------------------------------------------------------

Hi,
 
I have not have a sudoku today, so I tried to create a Top-Posters-List that not rely only on the count of posts. :)

But the line 41, where the ratio is calculated, needs to be corrected.
If someone have a better math for it, please post it.
 

<?php
//---------------------------------------------------------------- GLOBAL CONFIG

    define('PW_MEMBERS_URL', 'http://processwire.com/talk/members/?sort_key=posts&sort_order=desc&max_results=60');
    define('PW_MEMBERSLIST_PATTERN_1', "/<ul class='ipsMemberList'>(.*?)<script type='text\/javascript'>/msi");
    define('PW_MEMBERSLIST_PATTERN_2', "/<li id='member_id_(.*?)'.*?<img src='(.*?)'.*?<\/ul>.*?<h3.*?<strong>(.*?)<\/strong>.*?<span class='number'>(.*?)<\/span>.*?·(.*?)post.*?<\/li>/msi");

//-------------------------------------------------------------- EXECUTABLE CODE

    $members = array();
    $urls = array(
        PW_MEMBERS_URL,
        PW_MEMBERS_URL . '&st=60',
        PW_MEMBERS_URL . '&st=120',
        PW_MEMBERS_URL . '&st=180',
        PW_MEMBERS_URL . '&st=240'
    );

    foreach($urls as $url) {
        $buffer = preg_match(PW_MEMBERSLIST_PATTERN_1, file_get_contents($url), $matches)===1 ? $matches[1] : null;
        if(is_null($buffer)) {
            echo "Something has going wrong with '$url'!";
            exit(1);
        }
        if(60===preg_match_all("/<li id='member_id_(.*?)'.*?<img src='(.*?)'.*?<\/ul>.*?<h3.*?<strong>(.*?)<\/strong>.*?<span class='number'>(.*?)<\/span>.*?·(.*?)post.*?<\/li>/msi", $buffer, $temps, PREG_SET_ORDER)) {
            foreach($temps as $temp) {
                $likes  = intval($temp[4]);
                $posts  = intval(str_replace(',','', trim($temp[5])));
                $member = array(
                    'id'      => intval($temp[1]),
                    'name'    => strip_tags($temp[3]),
                    'profile' => $temp[3],
                    'imgsrc'  => $temp[2],
                    'likes'   => $likes,
                    'posts'   => $posts
                );
                if(0==$likes) {
                    $member['ratio'] = 0; // intval( $posts / 50 );
                }
                else {
                    $member['ratio'] = intval((($likes / $posts) * 100) * ($likes)) + intval($posts / 5);
                }
                $members[] = $member;
            }
        }
    }

    $members = hn_array_sort($members, array('ratio','likes','posts'), true, true);

    // the TOP 100 
    echo "<table border='0' cellpadding='0' cellspacing='5'>\n<tr><th>ratio</th><th>name</th><th>likes</th><th>posts</th></tr>\n";
    for($i=0;$i<100;$i++) {
        $a = array_shift($members);
        echo "<tr><td>{$a['ratio']}</td><td>{$a['name']}</td><td>{$a['likes']}</td><td>{$a['posts']}</td></tr>\n";
    }
    echo "</table>\n";

exit(0);

//-------------------------------------------------------------------- FUNCTIONS

/** Sorts the values of a given multidimensional Array in hirarchical order of the sortlist
  * @shortdesc USAGE: $SORTED_Array = hn_array_sort($orig_array, array('field3','field1','field2'));
  **/
function hn_array_sort($a, $sl, $intvals=false, $descending=false, $casesensitive=true) {
    $GLOBALS['__HN_SORTVALUE_LIST_DESCENDING__'] = $descending;
    $GLOBALS['__HN_SORTVALUE_LIST_CASESENSITIVE__'] = $casesensitive;
    $GLOBALS['__HN_SORTVALUE_LIST__'] = $sl;
    if($intvals===true) {
        usort($a, 'hn_cmp_Values_intvals');
    }
    else {
        usort($a, 'hn_cmp_Values_strvals');
    }
    return $a;
}
// Callback for hn_array_sort()
function hn_cmp_Values_strvals($a, $b) {
    foreach($GLOBALS['__HN_SORTVALUE_LIST__'] as $f) {
        $strc = $GLOBALS['__HN_SORTVALUE_LIST_CASESENSITIVE__']===true ? strcmp($a[$f],$b[$f]) : strcasecmp($a[$f],$b[$f]);
        if($strc != 0) {
            if($GLOBALS['__HN_SORTVALUE_LIST_DESCENDING__']===true) {
                return $strc * (-1);
            }
            return $strc;
        }
    }
    return 0;
}
// Callback for hn_array_sort()
function hn_cmp_Values_intvals($a, $b) {
    foreach($GLOBALS['__HN_SORTVALUE_LIST__'] as $f) {
        if(intval($a[$f])===intval($b[$f])) {
            $intc = 0;
        }
        elseif(intval($a[$f])>intval($b[$f])) {
            $intc = $GLOBALS['__HN_SORTVALUE_LIST_DESCENDING__']===true ? -1 : 1;
        }
        else {
            $intc = $GLOBALS['__HN_SORTVALUE_LIST_DESCENDING__']===true ? 1 : -1;
        }
        if($intc !== 0) return $intc;
    }
    return 0;
}

EDIT: replaced the Line 41 with a new more suitable formula :)

Edited by horst
Link to comment
Share on other sites

I must confess I'm pretty confused by that math, can you explain the intention? Is it some kind of known and tested formula?

Edit: the only truly fair formula is one where Ryan stays on the top :)

  • Like 1
Link to comment
Share on other sites

r = $likes / $posts

and call it a day or make some sudoku ( :P)

Or very much better play some Go ! (can't believe nobody here plays)

Soma,

I play Go, and have been working at it for years!  The difficulty is in finding other people with the patience to play.

I agree with the idea of doing more than just a straight "like count."  There should be some reflection of the "like proportions."

Another matter to consider is what I would call "like density."  Does the user get likes from many different users, or does he/she have a smaller number of people who "like" him/her?

Thanks,

Matthew

  • Like 1
Link to comment
Share on other sites

I must confess I'm pretty confused by that math, can you explain the intention? Is it some kind of known and tested formula?

LOL, no, it's just a try and error. I want to have members with more likes than posts counted up, but also want to honor much posts. But it doesn't do it with a simple linear ratio, because a member with only 1 or 2 posts and 15 likes beats all, also ryan with 3000 likes and 6000 posts. So I have tried to build a relation between the ratio and amount of the two parts.

<german>Getreu dem Motto: "Trau keiner Statistik, es sei denn, du hast sie selbst gefälscht!"</german>

<hopefully-correct-translation>Keeping with the motto: "Trust no statistics, unless you yourself have forged it!"</hopefully-correct-translation>

Edit: the only truly fair formula is one where Ryan stays on the top :)

YEP!

r = $likes / $posts

and call it a day or make some sudoku ( :P)

 Or very much better play some Go ! (can't believe nobody here plays)

no, it isn't that simple.

oh, - you never have seen one of my sudokos :lol:

I once only have played Gobang, a simple form of it.

I agree with the idea of doing more than just a straight "like count."  There should be some reflection of the "like proportions."

Another matter to consider is what I would call "like density."  Does the user get likes from many different users, or does he/she have a smaller number of people who "like" him/her?

first point +1

second one: this would it make much more complex. And of course, than we also should take the profile-views into account? - or the posts per thread (in relation to the thread.length)?

:)

Link to comment
Share on other sites

And the time that people hesitated when giving the like. Do we have that info? :P

I think that must be done with ajax (so we are in DevTalk) with something like:

while(onMouseOver('likeButton')) {
     hesitationCounter++;
}
Link to comment
Share on other sites

Greetings,

There is also some luck involved. I have seen many posts where someone really spends some time giving a great answer to someone's question, but does not receive a "like" from the person who started the discussion.

Maybe we need to factor in how many times the words "thank you" appear right next to someone's name in a post, and encourage everyone to hit that "like" button if someone really helped you out!

Thanks,

Matthew

Link to comment
Share on other sites

Dear Mr.MetaData

It's not that simple? Well I guess you already know that the type of calculation you try to do is "impossible".

After all I don't really care. I'm sure there's some formula which would consider different aspects, but none of them will be speaking something different than what already is seen. Those calculations are complicated and lead to results you'd have to put some bias/weight into it and it will never be "correct" considering you can't put all factors into account. To make it short, not worth the effort. 

What I would recommend is doing different list, you can sort by count of likes, post, ratio.. and everybody can read what he likes out of it.

  • Like 1
Link to comment
Share on other sites

Here is a pretty simple and balanced calculation: ( Likes / Posts ) * Likes

You should try to stick with likes and post, everything else is noise. If you try to do something very accurate you will be giving to much importance to something that it's not more than a fun thing to do.

If you want you can give some extra points. Here are some suggestions:

niknames that start with "d": multiply the result by 2;

avatar with lots of white space: 400 extra points;

no signature: 500 extra points;

;)

  • Like 1
Link to comment
Share on other sites

Not to mention some old foxes had thousands of posts on old forums, that didn't have likes (there was some kind of karma system, but it didn't get converted). So the data is somewhat corrupted already (makes it harder to get "Ryan is first" result :))..

Fun experiement still and happy to see the final list. 

Link to comment
Share on other sites

Greetings,

We can really have fun with this.

How about giving more weight to posts when the posts...

- Contain <code> tags

- Receive "likes" from people who have more likes than you

- Receive "likes" from people who have been members longer than you

- Appear in certain boards (for example, "API & Coding," rather than "Pub")

Thanks,

Matthew

Link to comment
Share on other sites

Not to mention some old foxes had thousands of posts on old forums, that didn't have likes (there was some kind of karma system, but it didn't get converted). So the data is somewhat corrupted already (makes it harder to get "Ryan is first" result :)).. 

I think I might have manually added the karma points (can't really remember) but not sure how widely used the karma system was - certainly there is a lot more love nowadays with the likes system working overtime to keep up with the increase in posts :)

Link to comment
Share on other sites

Dear Mr.MetaData

It's not that simple? Well I guess you already know that the type of calculation you try to do is "impossible".

[...]

To make it short, not worth the effort.

Yeah, I think finally that hits the nail!

Well, now there's more time for sudoku :lol:

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...