Sample class with a unit test
Also from a job interview a while back.
Here is the class that they gave me, which I extended -
class YPSet
#new and improved (sorry for the double email)
def initialize(*args)
@collect = []
args.each do |this|
@collect << this.to_i
end
@collect.sort!
@count = @collect.size
end
def average
sum = 0
@collect.each do |this|
sum+=this.to_f
end
(sum/@count)
end
def first_rec
@collect[0] ? @collect[0].to_i : nil
end
def lowest
first_rec
end
def highest
@collect[@count-1] ? @collect[@count-1].to_i : nil
end
def median
even_check=0
@collect.each do |this|
#loop to skip even method which is not importing properly
even_check = even_check==0 ? 1 : 0
end
is_even = even_check == 0 ? true : false
if is_even
#average median
half_position = (@count/2)
#first value
x1 = @collect[half_position-1]
#second value
x2 = @collect[half_position]
((x1+x2).to_f/2)
else
#single target
target_position = ((@count.to_i-1)/2) + 1
# value
@collect[target_position-1]
end
end
def average_dev
#return average deviation from main average per item
sum_of_deviations = 0
ave = self.average
@collect.each do |this|
sum_of_deviations += (this.to_f-ave).abs
end
sum_of_deviations/@count.to_i
end
def number_of_odds
count = 0
@collect.each do |this|
even_check = 0
for x in 1..this
#loop to skip even method (again)
even_check = even_check==0 ? 1 : 0
end
count += even_check
end
count
end
def number_of_evens
@count - number_of_odds
end
def partition(subdivisions)
#split into evenly sized partitions
single_part_size = (@count/subdivisions).to_i
new_array = []
cur_division = 1
x = 0
count_leftover = @count % subdivisions
original_leftover_count = count_leftover
while cur_division <= subdivisions
sub_array = []
while (x < ((single_part_size*cur_division) +
(cur_division<=original_leftover_count && original_leftover_count>0 ? (cur_division
And the unit test I wrote for it -
require "test/unit"
require "yp_set"
class YPSetTest < Test::Unit::TestCase
def setup
end
def test_should_calculate_average
assert_equal 6, YPSet.new(8, 10, 2, 6, 4).average
assert_equal 5.5, YPSet.new(10, 11, 0, 1).average
end
# The median is the middle value in a set of values. If there are
# an even number of values, it should be the average of the two middle
# values
def test_should_calculate_median
assert_equal 6, YPSet.new(8, 10, 2, 6, 4).median
assert_equal 4.5, YPSet.new(10, 0, 1, 9, 8, 1).median
end
def test_should_calculate_with_string_args
assert_equal 2, YPSet.new(1, "2", 3, "2", 2).average
assert_equal 3, YPSet.new("7", "2", 3, "8", 2).median
end
def test_should_be_ordered_correctly
#added per point #3
assert_equal 2, YPSet.new(9, "11", 2, "2", 6).first_rec
end
def test_average_dev
#added per point #4
assert_equal 2, YPSet.new(1, 1, 2, 2, 3, 9).average_dev
end
def test_lowest_and_highest
#added per point #4
assert_operator YPSet.new(99, 44, 33).lowest, "<", YPSet.new(33, 99, 44).highest
end
def test_number_of_evens
#added per point #4 - no need to test odds as they use the same function
assert_equal 6, YPSet.new(99, 44, 33, 2, 6, 8, 9, 12, 14).number_of_evens
end
def test_should_split_into_evenly_sized_subsets
values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
subsets = YPSet.new(*values).partition(3)
assert_equal 3, subsets.length
subsets.each do |subset|
assert_equal 5, subset.length
end
assert_equal values.length, subsets.flatten.length
values << 16
subsets = YPSet.new(*values).partition(3)
assert_equal 3, subsets.length
subsets.each do |subset|
assert_in_delta 5, subset.length, 1
end
assert_equal values.length, subsets.flatten.length
end
end
Good times!
Do the Alexa Dance - a review of Alexa reviews
I won't name names, or link links as it were, but ever since I discovered my own Alexa ranking(s) I have been obsessed with understanding how to optimize them - and as a matter of course I have read quite a few blogs about it. Without succumbing to the cliche of promising '20 Ways to Game Your Ranking', I will share what I know.
The only people that matter are the users that have installed the Alexa toolbar from http://www.alexa.com/site/download.
The traffic to your site of these users with the toolbar installed over the last 3 months is what determines your rank. So at the most basic level, the logical thing to do is bump up marketing (really?) and hope that a good percentage of those new clicks are Alexa users. This may be effective, but it is also wasteful to some degree.
It is also worth noting that the Alexa user base reputedly skews very much towards webmasters, so another good way to attract a stronger percentage of Alexa users relative to your total user base is to target content towards webmasters, like a laser. You zap in their clicks with post titles like '20 Sure Fire Tips on How to Be An Alexa Jedi' or 'I Made It Into the Alexa Top 1000 - In Only 10 Minutes!'. Of course you also need to have real stuff for them to read, or else the Jedi jokes can get your Force cut off. Anyway, my angle is that I work with Ruby on Rails, I post about Ruby On Rails, and I am a webmaster - so there's your targeted audience.
That being said, I have started a new category (http://www.digbox.net/index.php/alexa/) to track my newfound obsession. And if you are reading this and haven't already installed your very own toolbar then you don't deserve to be reading this, and I'll probably cry myself to sleep tonight. I hope you're happy.
Tune in next week for more observations.
polymorphic user list class part II
This is part II of a series.
start here: http://www.digbox.net/index.php/RoR/polymorphic-user-list-class
class User < ActiveRecord::Base
has_many :user_lists
has_many :invites
def join_group(id)
x = UserList.new
x.user_id = self.id
x.user_listable_type = "Group"
x.user_listable_id = id
if x.save
return true
else
return false
end
end
def join_project(id)
x = UserList.new
x.user_id = self.id
x.user_listable_type = "Project"
x.user_listable_id = id
if x.save
return true
else
return false
end
end
def join_event(id)
x = UserList.new
x.user_id = self.id
x.user_listable_type = "Event"
x.user_listable_id = id
if x.save
return true
else
return false
end
end
def groups
return UserList.find(:all, :conditions => ["user_listable_type ='Group' and user_id = ?", self.id])
end
def projects
return UserList.find(:all, :conditions => ["user_listable_type ='Project' and user_id = ?", self.id])
end
def events
return UserList.find(:all, :conditions => ["user_listable_type ='Event' and user_id = ?", self.id])
end
end
add aggregates to a group by
Pull in YTD aggregates, along with the numbers grouped by month - good example of a self-join as well as a 'derived table' which in this example is called 'counted'.
select s.product, count(s.serial_number) number_sold, year(s.item_date) y, month(s.item_date) m, counted.units
from sales s
join (select product, count(serial_number) units from sales group by product) counted on s.product = counted.product
group by s.product, year(s.item_date), month(s.item_date)
order by s.product, year(s.item_date), month(s.item_date)
the green search - aka el buscario verte
Find lovely green things to read and otherwise consume.
:: Next >>