<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: ruby code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Mon, 08 Sep 2008 05:46:34 GMT</pubDate>
    <description>DZone Snippets: ruby code</description>
    <item>
      <title>Simple S3 utils - copy bucket to bucket</title>
      <link>http://snippets.dzone.com/posts/show/4935</link>
      <description>Some simple S3 utils in Ruby&lt;br /&gt;&lt;br /&gt;Specifically written to copy one bucket to another (for testing on production on staging)&lt;br /&gt;&lt;br /&gt;PLEASE BE CAREFUL WITH THIS - THERE IS CODE THAT DELETES ALL CONTENTS OF A BUCKET&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;a = AmazoneS3Asset.new&lt;br /&gt;a.copy_over_bucket("myapp_production", "myapp_production")&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;require 'aws/s3'&lt;br /&gt;require 'mechanize'&lt;br /&gt;&lt;br /&gt;class AmazonS3Asset&lt;br /&gt;  &lt;br /&gt;  include AWS::S3&lt;br /&gt;  S3ID = "your s3 id"&lt;br /&gt;  S3KEY = "your s3 key"&lt;br /&gt;  &lt;br /&gt;  def initialize&lt;br /&gt;    puts "connecting..."&lt;br /&gt;    AWS::S3::Base.establish_connection!(&lt;br /&gt;      :access_key_id     =&gt; S3ID,&lt;br /&gt;      :secret_access_key =&gt; S3KEY&lt;br /&gt;    )&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def delete_key(bucket, key)&lt;br /&gt;    if exists?(bucket, key) &lt;br /&gt;      S3Object.delete key, bucket&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def empty_bucket(bucket)&lt;br /&gt;    bucket_keys(bucket).each do |k|&lt;br /&gt;      puts "deleting #{k}"&lt;br /&gt;      delete_key(bucket,k)&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def bucket_keys(bucket)&lt;br /&gt;    b = Bucket.find(bucket)&lt;br /&gt;    b.objects.collect {|o| o.key}&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def copy_over_bucket(from_bucket, to_bucket)&lt;br /&gt;    puts "Replacing #{to_bucket} with contents of #{from_bucket}"&lt;br /&gt;    #delete to_bucket&lt;br /&gt;    empty_bucket(to_bucket)&lt;br /&gt;    bucket_keys(from_bucket).each do |k|&lt;br /&gt;      copy_between_buckets(from_bucket, to_bucket, k)&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def copy_between_buckets(from_bucket, to_bucket, from_key, to_key = nil)&lt;br /&gt;    if exists?(from_bucket, from_key)&lt;br /&gt;      to_key = from_key if to_key.nil?&lt;br /&gt;      puts "Copying #{from_bucket}.#{from_key} to #{to_bucket}.#{to_key}"&lt;br /&gt;      url = "http://s3.amazonaws.com/#{from_bucket}/#{from_key}"&lt;br /&gt;      filename = download(url)&lt;br /&gt;      store_file(to_bucket,to_key,filename)&lt;br /&gt;      File.delete(filename)&lt;br /&gt;      return "http://s3.amazonaws.com/#{to_bucket}/#{to_key}"&lt;br /&gt;    else&lt;br /&gt;      puts "#{from_bucket}.#{from_key} didn't exist"&lt;br /&gt;      return nil&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def store_file(bucket, key, filename)&lt;br /&gt;     puts "Storing #{filename} in #{bucket}.#{key}"&lt;br /&gt;     S3Object.store(&lt;br /&gt;      key,&lt;br /&gt;      File.open(filename),&lt;br /&gt;      bucket,&lt;br /&gt;      :access =&gt; :public_read&lt;br /&gt;      )&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def download(url, save_as = nil)&lt;br /&gt;    if save_as.nil?&lt;br /&gt;      Dir.mkdir("amazon_s3_temp") if !File.exists?("amazon_s3_temp")&lt;br /&gt;      save_as = File.join("amazon_s3_temp",File.basename(url))&lt;br /&gt;    end&lt;br /&gt;    begin&lt;br /&gt;      puts "Saving #{url} to #{save_as}"&lt;br /&gt;      agent = WWW::Mechanize.new {|a| a.log = Logger.new(STDERR) }&lt;br /&gt;      img = agent.get(url)&lt;br /&gt;      img.save_as(save_as)&lt;br /&gt;      return save_as&lt;br /&gt;    rescue&lt;br /&gt;      raise "Failed on " + url + "  " + save_as&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def exists?(bucket,key)&lt;br /&gt;    begin&lt;br /&gt;      res = S3Object.find key, bucket&lt;br /&gt;    rescue &lt;br /&gt;      res = nil&lt;br /&gt;    end&lt;br /&gt;    return !res.nil?&lt;br /&gt;  end&lt;br /&gt;      &lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sun, 30 Dec 2007 20:13:56 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4935</guid>
      <author>wiseleyb (ben)</author>
    </item>
    <item>
      <title>Weighted Mean</title>
      <link>http://snippets.dzone.com/posts/show/4613</link>
      <description>Weighted mean ( http://en.wikipedia.org/wiki/Mean#Weighted_arithmetic_mean )&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class Array&lt;br /&gt;  #sum (and mean) found on http://snippets.dzone.com/posts/show/2161&lt;br /&gt;  def sum&lt;br /&gt;    inject( nil ) { |sum,x| sum ? sum + x.to_f : x.to_f }&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def mean&lt;br /&gt;    sum.to_f / size&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  #http://en.wikipedia.org/wiki/Mean#Weighted_arithmetic_mean&lt;br /&gt;  def weighted_mean(weights_array)&lt;br /&gt;    raise "Each element of the array must have an accompanying weight.  Array length = #{self.size} versus Weights length = #{weights_array.size}" if weights_array.size != self.size&lt;br /&gt;    w_sum = weights_array.sum&lt;br /&gt;    w_prod = 0&lt;br /&gt;    self.each_index {|i| w_prod += self[i] * weights_array[i].to_f}&lt;br /&gt;    w_prod.to_f / w_sum.to_f&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Example&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&gt;&gt; a = [1,2,3]&lt;br /&gt;=&gt; [1, 2, 3]&lt;br /&gt;&gt;&gt; w = [1,1,1]&lt;br /&gt;=&gt; [1, 1, 1]&lt;br /&gt;&gt;&gt; a.weighted_arithmetic_mean(w)&lt;br /&gt;=&gt; 2.0&lt;br /&gt;&gt;&gt; a.mean&lt;br /&gt;=&gt; 2.0&lt;br /&gt;&gt;&gt; w = [5,2,1]&lt;br /&gt;=&gt; [5, 2, 1]&lt;br /&gt;&gt;&gt; a.weighted_arithmetic_mean(w)&lt;br /&gt;=&gt; 1.5&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Wed, 03 Oct 2007 21:29:12 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4613</guid>
      <author>wiseleyb (ben)</author>
    </item>
    <item>
      <title>Weighted Random array selection</title>
      <link>http://snippets.dzone.com/posts/show/4571</link>
      <description>Say you have an array of ['apples', 'oranges', 'bananas', 'kiwis']&lt;br /&gt;&lt;br /&gt;Selecting a random item is simple enough&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  arr = ['apples', 'oranges', 'bananas', 'kiwis']&lt;br /&gt;  arr[rand(arr.size)]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;But say you want to have apples come up 50% of the time, oranges 25%, bananas 15% and kiwis 10% ... &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  class Array&lt;br /&gt;    &lt;br /&gt;    #sum (and mean) found on http://snippets.dzone.com/posts/show/2161&lt;br /&gt;    def sum&lt;br /&gt;      inject( nil ) { |sum,x| sum ? sum+x : x }&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def probability(spread = 2)&lt;br /&gt;      z = 1.0&lt;br /&gt;      collect {|x| z = z / spread}&lt;br /&gt;    end&lt;br /&gt;    def weighted_random_index(probability_array = probability(2) )&lt;br /&gt;      size.times do |x|&lt;br /&gt;        return x if rand &lt; probability_array[0..x].sum&lt;br /&gt;      end&lt;br /&gt;      return 0&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def get_weighted_random_item(probability_array = probability(2))&lt;br /&gt;      self[weighted_random_index(probability_array)]&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def get_weighted_random_indexes(num_items, p = probability(2))&lt;br /&gt;      res = []&lt;br /&gt;      escape = 1000&lt;br /&gt;      while res.size &lt; num_items and escape &gt; 0&lt;br /&gt;        escape -= 1&lt;br /&gt;        tmp = weighted_random_index(p) &lt;br /&gt;        res &lt;&lt; tmp unless res.include?(tmp)&lt;br /&gt;      end&lt;br /&gt;      return res.sort&lt;br /&gt;    end&lt;br /&gt;  &lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;arr = ['apples', 'oranges', 'bananas', 'kiwis']&lt;br /&gt;10.times do |i|&lt;br /&gt;  puts arr.get_weighted_random_item([0.5, 0.25, 0.15, 0.10])&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;oranges&lt;br /&gt;oranges&lt;br /&gt;apples&lt;br /&gt;apples&lt;br /&gt;bananas&lt;br /&gt;apples&lt;br /&gt;apples&lt;br /&gt;bananas&lt;br /&gt;oranges&lt;br /&gt;apples&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I'm sure there's some math term for this but I'm calling it 'spread' until I learn otherwise.  I put in a default probability array of p = p / 2 which gives you (for an array of 4)&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;arr.probability&lt;br /&gt;=&gt; [0.5, 0.25, 0.125, 0.0625]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;On larger arrays the probabilities will get (for all practicle purposes) zero quickly&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;arr = [1,2,3,4,5,6,7,8,9]&lt;br /&gt;=&gt; [1, 2, 3, 4, 5, 6, 7, 8, 9]&lt;br /&gt;arr.probability&lt;br /&gt;=&gt; [0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125, 0.00390625, 0.001953125]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I put in a simple spread concept to spread out the probabilities a bit more... the higher the spread, the more even the probability distribution (this varies a lot with array size - but here's a simple example):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;   arr = ['apples', 'oranges', 'bananas', 'guava']&lt;br /&gt;   iterations = 10000&lt;br /&gt;   4.times do |t|&lt;br /&gt;     p = arr.probability(t+2)&lt;br /&gt;     res = Array.new(arr.size).fill(0)&lt;br /&gt;     iterations.times do |x|&lt;br /&gt;       res[arr.weighted_random_index(p)] += 1&lt;br /&gt;     end&lt;br /&gt;     res2 = res.collect {|x| (x/iterations.to_f) * 100}&lt;br /&gt;     puts "For probability spread #{t+2}"&lt;br /&gt;     puts "Results #{res2.join(", ")} = #{res2.sum}"&lt;br /&gt;     puts ""&lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;   For probability spread 2&lt;br /&gt;   Results 49.71, 37.55, 11.35, 1.39 = 100.0&lt;br /&gt;&lt;br /&gt;   For probability spread 3&lt;br /&gt;   Results 43.44, 29.99, 17.79, 8.78 = 100.0&lt;br /&gt;&lt;br /&gt;   For probability spread 4&lt;br /&gt;   Results 48.3, 23.56, 16.73, 11.41 = 100.0&lt;br /&gt;&lt;br /&gt;   For probability spread 5&lt;br /&gt;   Results 54.22, 19.31, 14.65, 11.82 = 100.0&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Here is a longer example:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;    def weighted_random_index_example&lt;br /&gt;      arr = ['apples', 'oranges', 'bananas', 'guava']&lt;br /&gt;      puts "Sample array = [#{arr.join(",")}]"&lt;br /&gt;      p = [0.5,0.25, 0.15, 0.10]&lt;br /&gt;      puts "Probability that each will show up [#{p.join(', ')}]"&lt;br /&gt;      puts "1000 runs..."&lt;br /&gt;      res = Array.new(arr.size).fill(0)&lt;br /&gt;      1000.times do |t|&lt;br /&gt;        res[arr.weighted_random_index(p)] += 1&lt;br /&gt;      end&lt;br /&gt;      res2 = res.collect {|x| (x/1000.0) * 100}&lt;br /&gt;      puts "Results:"&lt;br /&gt;      4.times do |t|&lt;br /&gt;        puts "    #{arr[t]}: #{res2[t]}%"&lt;br /&gt;      end&lt;br /&gt;      &lt;br /&gt;      puts ""&lt;br /&gt;      puts "You can also use more spread out probability arrays"&lt;br /&gt;      p = arr.probability(3)&lt;br /&gt;      puts "Probability that each will show up with a spread of 3 [#{p.join(', ')}]"&lt;br /&gt;      puts "1000 runs..."&lt;br /&gt;      res = Array.new(arr.size).fill(0)&lt;br /&gt;      1000.times do |t|&lt;br /&gt;        res[arr.weighted_random_index(p)] += 1&lt;br /&gt;      end&lt;br /&gt;      res2 = res.collect {|x| (x/1000.0) * 100}&lt;br /&gt;      puts "Results:"&lt;br /&gt;      4.times do |t|&lt;br /&gt;        puts "    #{arr[t]}: #{res2[t]}%"&lt;br /&gt;      end&lt;br /&gt;      &lt;br /&gt;      puts ""&lt;br /&gt;      puts "You can also just get selected indexes"&lt;br /&gt;      puts "arr.get_weighted_random_indexes(3,p) = [#{arr.get_weighted_random_indexes(3,p).join(', ')}]"&lt;br /&gt;      &lt;br /&gt;      puts "The probability spread will depend on the number of items in your array - for an array of 4 it looks like this:"&lt;br /&gt;      8.times do |t|&lt;br /&gt;        puts "  probability(#{t+2}):  [#{arr.probability(t+2).collect {|x| sprintf('%0.5f',x)}.join(', ')}]"&lt;br /&gt;      end&lt;br /&gt;      return nil&lt;br /&gt;    end&lt;br /&gt;    weighted_random_index_example&lt;br /&gt;&lt;br /&gt;Outputs...&lt;br /&gt;Sample array = [apples,oranges,bananas,guava]&lt;br /&gt;Probability that each will show up [0.5, 0.25, 0.15, 0.1]&lt;br /&gt;1000 runs...&lt;br /&gt;Results:&lt;br /&gt;    apples: 49.1%&lt;br /&gt;    oranges: 38.3%&lt;br /&gt;    bananas: 11.3%&lt;br /&gt;    guava: 1.3%&lt;br /&gt;&lt;br /&gt;You can also use more spread out probability arrays&lt;br /&gt;Probability that each will show up with a spread of 3 [0.333333333333333, 0.111111111111111, 0.037037037037037, 0.0123456790123457]&lt;br /&gt;1000 runs...&lt;br /&gt;Results:&lt;br /&gt;    apples: 43.6%&lt;br /&gt;    oranges: 29.2%&lt;br /&gt;    bananas: 18.0%&lt;br /&gt;    guava: 9.2%&lt;br /&gt;&lt;br /&gt;You can also just get selected indexes&lt;br /&gt;arr.get_weighted_random_indexes(3,p) = [0, 1, 3]&lt;br /&gt;The probability spread will depend on the number of items in your array - for an array of 4 it looks like this:&lt;br /&gt;  probability(2):  [0.50000, 0.25000, 0.12500, 0.06250]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;</description>
      <pubDate>Tue, 25 Sep 2007 21:55:19 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4571</guid>
      <author>wiseleyb (ben)</author>
    </item>
  </channel>
</rss>
