?

Log in

[theme] - [expressive] - [tagspage: limited list of tags] - S2 Layers [entries|archive|friends|userinfo]
S2 Layers

[ website | advanced customization ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Links
[Links:| how to post tags page ]
[affiliated communities| fblayers ]

[theme] - [expressive] - [tagspage: limited list of tags] [Mar. 2nd, 2007|01:52 pm]
S2 Layers

s2layers

[kunzite1]
[Tags|, , ]

in response to wasd's s2expressive post.

class MyClass {
  function quicksort(string[] list, int start, int end) : string[];
  function quicksort(string[] list)                     : string[];
}

###############
# <quicksort> #
###############
#// These two functions perform sorting capabilities
#//
#// Credit goes to 'Tony Chang <tychang1 [at] uiuc [dot] edu>'
#// See: http://www.livejournal.com/customize/advanced/layersource.bml?id=54714
#// % Partitions then recursively calls.
#// % Tested up to 172 sortable elements in a string array
function MyClass::quicksort(string[] list, int start, int end) : string[] {
  if ($end <= $start) {
    return $list;
  }
  
  #// Pick a pivot and move to the front
  var int pivot  = rand($start, $end);
  var string tmp = $list[$start];
  $list[$start]  = $list[$pivot];
  $list[$pivot]  = $tmp;
  
  #// Now Partition
  var int left  = ($start + 1);
  var int right = $end;
  
  foreach var int i ($start .. ($end - 2)) {
    if ($list[$left] > $list[$start]) {
      #// Swap the left and the right, then move the right back
      $tmp          = $list[$left];
      $list[$left]  = $list[$right];
      $list[$right] = $tmp;
      $right--;
    } else {
      $left++;
    }
  }

  # put the pivot back in the middle
  if ($list[$start] < $list[$left]) {
    #// Swap $start and ($left - 1)
    $tmp               = $list[$start];
    $list[$start]      = $list[($left - 1)];
    $list[($left - 1)] = $tmp;
    $pivot             = ($left - 1);
  } else {
    #// Swap $start and $left
    $tmp          = $list[$start];
    $list[$start] = $list[$left];
    $list[$left]  = $tmp;
    $pivot        = $left;
  }
  
  #// Sort either side of the pivot
  $list = $this->quicksort($list, $start,       ($pivot - 1));
  $list = $this->quicksort($list, ($pivot + 1), $end);
  
  return $list;
}

#// Recursing Function
function MyClass::quicksort(string[] list) : string[] {
  return $this->quicksort($list, 0, size $list - 1);
}
################
# </quicksort> #
################

function TagsPage::print_body() {
  var TagDetail[]   tags      = $this->visible_tag_list(); # get available tags
  var TagDetail[]{} my_tags   = {};                        # repackage tags, group by use count
  var string{}{}    cloud     = {};                        # final package for individual tags
  var string[]      tag_names = [];                        # keep track of tag names that are in final set
  var int           max_count = 0;                         # keep track of max number of uses for any tag
  var int           max_list  = 20;                        # max number of tags to list

  # print opening to Expressive's TagsPage
  print safe """<h2 class="asset-name page-header2">$*text_tags_page_header</h2>""";

  # cycle thru tags
  foreach var TagDetail t ($tags) {
    # get highest count
    if($t.use_count > $max_count) {
      $max_count = $t.use_count;
    }

    # get existing set of tags for this use count
    var TagDetail[] array  = $my_tags{$t.use_count};

    # add this tag
    $array[size($array)]   = $t;

    # save
    $my_tags{$t.use_count} = $array;
  }

  # cycle thru sorted tags
  foreach var int i (0 .. $max_count) {
    # get tag group by use count
    var TagDetail[] ts = $my_tags{$max_count - $i};

    # if this use count has tags
    if($ts) {
      # cycle thru tags with this use count
      foreach var TagDetail t ($ts) {
        var string{} hash = {};
        $hash{"url"}                 = $t.url;            # copy url
        $hash{"uses"}                = $t.use_count + ""; # copy use count
        $hash{"sec"}                 = $t.visibility;     # copy security/visibility
        $hash{"size"}                = ($t.use_count > 1) ? (((($t.use_count * 16) / $max_count) + 7) + "") : "7"; # calculate font size
        $cloud{$t.name}              = $hash;   # add hash to cloud
        $tag_names[size($tag_names)] = $t.name; # add tag name to final set record

        # decrement max list var because we've added a tag to the final set
        $max_list--;

        # if we're at the end of the list, stop adding more
        if($max_list <= 0) {
          break;
        }
      }
    }

    # if we're at the end of the list, stop adding more
    if($max_list <= 0) {
      break;
    }
  }

  # instantiate MyClass object
  var MyClass mc = new MyClass;

  # sort tag names
  $tag_names = $mc->quicksort($tag_names);

  # cycle thru final set
  foreach var string name ($tag_names) {
    var string{} hash = $cloud{$name}; # get tag data
    var string   url  = $hash{"url"};  # get url
    var string   uses = $hash{"uses"}; # get uses
    var string   sec  = $hash{"sec"};  # get security/visibility
    var string   size = $hash{"size"}; # get font size
    var string   alt  = $uses + " use" + (int($uses) != 1 ? "s" : "") + ", " + $sec; # built alt string

    # put it all together
    """<a href="$url" alt="$alt" title="$alt" style="font-size: ${size}px;">$name</a> """;
  }
}
linkReply

Comments:
[User Picture]From: av8rmike
2007-03-04 12:57 am (UTC)
Hmmm, can you do a heap sort or merge sort with S2? ;)

I was going to suggest sorting tags by usage first, selecting the top 20, then re-sorting. However, it's probably not efficient to do so much sorting, and I see that quicksort function works only on string arrays.
(Reply) (Parent) (Thread)
[User Picture]From: kunzite1
2007-03-04 03:35 am (UTC)
you can do heap or merge if you can simplify it into s2 functions. :P

this is what i do:
  1. run through TagDetails (Page::visible_tag_list()) to get highest use count while making a hash of TagDetails based on TagDetail.use_count
  2. run through hash while copying TagDetail data, calculating font size, and creating an array of tag names (strings), then stop when max amount of list items has been reached
  3. quicksort tag names (strings) so that we know which order to print them in
  4. run through tag names (strings) and print tag links based on saved information (strings) in hash
what you seem to be proposing is:
  1. sort linear array of TagDetails (Page::visible_tag_list()) by usage (TagDetail.use_count), but stop when max amount of list items is reached
  2. sort resulting array into alpha order by tag name (TagDetail.name)
  3. run through array and print tag links based on information in TagDetail objects
your design definitely seems simpler. but it uses more function calls and your sorting algorithms might be hard to implement in s2 depending on all the functions that they would need.

with quicksort, i think the following lines could be changed to make it work:

- function quicksort(string[] list, int start, int end) : string[];
- function quicksort(string[] list)                     : string[];
+ function quicksort(TagDetail[] list, int start, int end) : TagDetail[];
+ function quicksort(TagDetail[] list)                     : TagDetail[];

- if ($list[$left] > $list[$start]) {
+ if ($list[$left].name > $list[$start].name) {

- if ($list[$start] < $list[$left]) {
+ if ($list[$start].name < $list[$left].name) {
(Reply) (Parent) (Thread)