diff --git a/lib/ranking/README.md b/lib/ranking/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0f01c85eb3a4cd2569e817afd5c898141c39f2ff --- /dev/null +++ b/lib/ranking/README.md @@ -0,0 +1,18 @@ +# Ranking docs + +# Refactored + +```ruby +items = [] +items << Ranking::Item.new("ax",1,1,1,["otherStuffA","lala",'a']) +items << Ranking::Item.new("bx",2,2,2,[1,2,3,"teste","lblb",'b']) +items << Ranking::Item.new("cx",1,1,99,[3,2,1,"teste","lclc",'c']) + +rater = Ranking::Rater.new(Ranking::Strategies::BasicRater.new(1000, 1, 100)) +rater.sortByRate(items).each do |i| + p i.name +end +``` + +## Output + - ordered array of Items, starting from the most ranked to the least \ No newline at end of file diff --git a/lib/ranking/item.rb b/lib/ranking/item.rb new file mode 100644 index 0000000000000000000000000000000000000000..33fc5009b43282fb1ab453f477ff8fcbadd47ae3 --- /dev/null +++ b/lib/ranking/item.rb @@ -0,0 +1,18 @@ +# This class represents an item of ranking +class Ranking::Item + # name = name of object + # views = view count + # downloads = download count + # likes = like count + # info = just for convinience of sorting it together, won't be touched + attr_accessor :name, :views, :downloads, :likes, :info + + def initialize(name, views = 0, downloads = 0, likes = 0, info = nil) + @name = name + @views = views + @downloads = downloads + @likes = likes + @info = info + end + +end \ No newline at end of file diff --git a/lib/ranking/rated_item.rb b/lib/ranking/rated_item.rb new file mode 100644 index 0000000000000000000000000000000000000000..baa5aa8ec8a304efd2bdbad02187b7093b0e7ea7 --- /dev/null +++ b/lib/ranking/rated_item.rb @@ -0,0 +1,10 @@ +# This class represents an item rated in ranking +# Have an association with a rank item +class Ranking::RatedItem + attr_accessor :item, :rate + + def initialize(item, rate) + @item = item + @rate = rate + end +end \ No newline at end of file diff --git a/lib/ranking/rater.rb b/lib/ranking/rater.rb new file mode 100644 index 0000000000000000000000000000000000000000..75b3d40181a6f580dfef543a4e56e872e59edb74 --- /dev/null +++ b/lib/ranking/rater.rb @@ -0,0 +1,11 @@ +class Ranking::Rater + + def initialize(rater_strategy) + @rater = rater_strategy + end + + def sortByRate(items) + @rater.sortByRate items + end + +end \ No newline at end of file diff --git a/lib/ranking/strategies/basic_rater.rb b/lib/ranking/strategies/basic_rater.rb new file mode 100644 index 0000000000000000000000000000000000000000..069740879e7aa0c7a67d2301d6f90b0fc0eb1a63 --- /dev/null +++ b/lib/ranking/strategies/basic_rater.rb @@ -0,0 +1,22 @@ +class Ranking::Strategies::BasicRater < Ranking::Strategy + + def sortByRate(items) + items.zip( items.size.downto(1) ) + .collect { |item,reverseIndex| self.rateItem( item, reverseIndex ) } + .sort { |itemA,itemB| itemA.rate <=> itemB.rate } + .collect { |ri| ri.item } + .reverse # Best ranked comes first + end + + private + + def rateItem(item, inversePosition) + positionRating = inversePosition * @positionWeight + useRating = (item.downloads < item.views ? item.downloads : item.views) * @useWeight + likeRating = item.likes * @likeWeight + + rate = positionRating + useRating + likeRating + build_rated_item item, rate + end + +end \ No newline at end of file diff --git a/lib/ranking/strategy.rb b/lib/ranking/strategy.rb new file mode 100644 index 0000000000000000000000000000000000000000..ffce28174a077d6fc9cf75ec6a12a4176d19f928 --- /dev/null +++ b/lib/ranking/strategy.rb @@ -0,0 +1,15 @@ +class Ranking::Strategy + + def initialize(positionWeight = nil, useWeight = nil, likeWeight = nil) + @positionWeight = (positionWeight == nil ? 1000 : positionWeight) + @useWeight = (useWeight == nil ? 3 : useWeight) + @likeWeight = (likeWeight == nil ? 100 : likeWeight) + end + + protected + + def build_rated_item(item, rate) + Ranking::RatedItem.new(item, rate) + end + +end \ No newline at end of file